- 赵一静 的博客
七月暑期集训7月19日DAY11题解
- @ 2024-7-19 15:17:19
小W的病毒歼灭战(queue队列)
思路没想到的原因
当时没有什么思路,之后要把数据结构好好复习一遍。
思路
用一个队列来统计,遇到没有的入队,全满了就让第一个出队,并。
👀️代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+10;
int a[N],f[N];
queue<int> q;
int hh=0,tt=-1;
signed main(){
freopen("bd.in","r",stdin);
freopen("bd.out","w",stdout);
int m,n;
cin >>m>>n;
for(int i=1;i<=n;i++){
cin >>a[i];
q.push(a[i]);
}
int cnt=0;
for(int i=1;i<=n;i++){
int w=q.front();
q.pop();
bool flag=1;
for(int j=hh;j<=tt;j++){
if(f[j]==w) flag=0;
}
if(flag==true){
cnt++;
if(tt-hh+1==m) hh++;
f[++tt]=w;
}
}
cout <<cnt;
return 0;
}
小田的三倍数(模拟)
思路没想到的原因
写错了,这个错不该犯,以后一定一定要注意!!!
思路
按照平常的方法,普通模拟就能过。但是注意:!!!所以暴力过不了。我们知道,只要各位数相加的和是的倍数,那么这个数就是的倍数。用来存,判断是否每一位的和是的倍数,最后输出(还有,记得开 )。
代码
#include <bits/stdc++.h>
using namespace std;
int main(){
freopen("three.in","r",stdin);
freopen("three.out","w",stdout);
long long t;
cin >>t;
while(t--){
long long ans=0,cnt=0;
long long n;
cin >>n;
for(int i=1;i<=n;i++){
string s;
cnt=0;
cin >>s;
for(int j=0;j<s.size();j++){
cnt+=(s[j]-'0')%3;
cnt=cnt%3;
}
ans+=cnt;
ans=ans%3;
}
if(ans==0){
cout <<"Yes"<<endl;
}else{
cout <<"No"<<endl;
}
}
return 0;
}
小田的省钱计划(最大子段和)
思路没想到的原因
只写了暴力算法,骗了分。没想到最大子段和。
思路
只需简单判断一下即可:
- 如果满足,那么;
- 否则。
要求与的最大值。
代码
#include <bits/stdc++.h>
using namespace std;
const int tt=1e5+10;
long long a[tt],f[tt];
int main(){
freopen("money.in","r",stdin);
freopen("money.out","w",stdout);
long long n,x;
long long ans=0;
cin >>n>>x;
for(int i=0;i<n;i++){
cin >>a[i];
a[i]-=x;
if(f[i-1]<0){
f[i]=a[i];
}else{
f[i]=f[i-1]+a[i];
}
ans=max(f[i],ans);
}
cout <<ans;
return 0;
}
计算表达式的值(数据结构)
思路
没啥思路,表达式求值模板题,只需加一个运算的特判。
代码
#include <bits/stdc++.h>
using namespace std;
stack<int> num;
stack<char> op;
void eval(){
int b=num.top();
num.pop();
int a=num.top();
num.pop();
char c=op.top();
op.pop();
int x;
if(c=='+') x=a+b;
else if(c=='-') x=a-b;
else if(c=='*') x=a*b;
else if(c=='/') x=a/b;
else{
x=a;
for(int i=2;i<=b;i++){
x*=a;
}
}
num.push(x);
}
unordered_map<char, int> pr{{'+',1},{'-',1},{'*',2},{'/',2},{'^',3}};
int main(){
freopen("bds.in","r",stdin);
freopen("bds.out","w",stdout);
string s;
cin >>s;
for(int i=0;i<s.size();i++){
auto c=s[i];
if(isdigit(c)){
int x=0,j=i;
while(j<s.size()&&isdigit(s[j])){
x=x*10+s[j]-'0';
j++;
}
i=j-1;
num.push(x);
}
else if(c=='(') op.push(c);
else if(c==')'){
while(op.top()!='(') eval();
op.pop();
}else{
while(op.size()&&op.top()!='('&&pr[c]<=pr[op.top()]){
eval();
}
op.push(c);
}
}
while(op.size()) eval();
cout <<num.top();
return 0;
}
永夜的报应(异或运算)
思路没想到的原因
想到了异或就是不进位的加法,但没想到只要把所有数字异或就行了。以后多积累题目。
思路
答案就是所有数的异或和。
代码
#include <bits/stdc++.h>
using namespace std;
const int tt=1e6+10;
long long a[tt];
int main(){
freopen("huiye.in","r",stdin);
freopen("huiye.out","w",stdout);
int n;
cin >>n;
for(int i=1;i<=n;i++){
cin >>a[i];
}
long long cnt=a[1];
for(int i=2;i<=n;i++){
cnt=a[i]^cnt;
}
cout <<cnt;
return 0;
}
数学题2(数学)
思路没想到的原因
没时间了,以后要注意时间分配。
思路
我们可以将所有约数都用哈希表存起来(是存每个数中出现了几次)。我们可以这样:先记录和那个数,前提是那个书不是在记录最大的约数(所有数中)由于如果是的倍数,那么也是。那个最大的约数是用来从它开始循环,找满足条件的最大约数。为了时间复杂度是,可以定义一个因为在循环中,是不会往回找的。来表示上一次到哪了。
代码
#include <bits/stdc++.h>
using namespace std;
const int tt=1e4+10;
int a[tt];
int max_x=0;
unordered_map<int,int> mp;
void f(int x){
mp[1]++;
if(x!=1){
mp[x]++;
}
max_x=max(max_x,x);
for(int i=2;i<=x/i;i++){
if(x%i==0){
mp[i]++;
}
if(x%i==0&&x/i!=i){
mp[x/i]++;
}
}
}
int main(){
freopen("math2.in","r",stdin);
freopen("math2.out","w",stdout);
int n;
cin >>n;
for(int i=1;i<=n;i++){
int x;
cin >>x;
f(x);
}
for(int i=1;i<=n;i++){
for(int j=max_x;j>=1;j--){
if(mp[j]>=i){
max_x=j;
cout <<j<<endl;
break;
}
}
}
return 0;
}