小W的病毒歼灭战(queue队列)

思路没想到的原因

当时没有什么思路,之后要把数据结构好好复习一遍。

思路

用一个队列来统计,遇到没有的入队,全满了就让第一个出队,并cnt++cnt++

👀️代码

#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;
}

小田的三倍数(模拟)

思路没想到的原因

freopenfreopen写错了,这个错不该犯,以后一定一定要注意!!!

思路

按照平常的方法,普通模拟就能过。但是注意:1a[i]101001≤a[i]≤10^{100}!!!所以暴力过不了。我们知道,只要各位数相加的和是33的倍数,那么这个数就是33的倍数。用stringstring来存a[i]a[i],判断是否每一位的和是33的倍数,最后输出(还有,记得开longlong longlong)。

代码

#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;
}

小田的省钱计划(最大子段和)

思路没想到的原因

只写了暴力算法,骗了4040分。没想到最大子段和

思路

只需简单判断一下即可:

  • 如果满足f[i1]<0f[i-1]<0,那么f[i]=a[i]f[i]=a[i]
  • 否则f[i]=f[i1]+a[i]f[i]=f[i-1]+a[i]

ansans要求ansansf[i]f[i]的最大值。

代码

#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(数学)

思路没想到的原因

没时间了,以后要注意时间分配

思路

我们可以将所有约数都用哈希表存起来(是存每个数中出现了几次)。我们可以这样:先记录11和那个数,前提是那个书不是11在记录最大的约数(所有数中)由于如果iixx的倍数,那么x/ix/i也是x/i!=i(x/i!=i)。那个最大的约数是用来从它开始循环,找满足mp[i]>=kmp[i]>=k条件的最大约数。为了时间复杂度是O(n)O(n),可以定义一个maxxmaxx因为在循环中,是不会往回找的。maxxmaxx来表示上一次到哪了。

代码

#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;
}

谢谢