NOIP题目(真TM变态)

一.递推算法

        A.错排问题

#include <bits/stdc++.h>
using namespace std;
int n;
long long f[21];
int main(){
	cin>>n;
	f[1]=0,f[2]=1;
	for (int i=3;i<=n;i++){
		f[i]=(i-1)*(f[i-1]+f[i-2]);
	}
	cout<<f[n]<<endl;
	return 0;
}

        .

#include <bits/stdc++.h>
using namespace std;
int f[1000001];
int k[2500000];
int n,l;
int main(){
	for (int i=1000000;i>=0;i--){
		if(i>=1001){
			f[i]=i-10;
		}
		else{
			f[i]=f[f[i+11]];
		}
	}
	while(true){
		cin>>k[n];
		if(k[n]==0) break;
		n++;
	}
	for (int i=0;i<n;i++){
		l=l^f[k[i]];
	}
	cout<<l<<endl;
	return 0;
}

#include <bits/stdc++.h>
using namespace std;
int n,m,num,l;
int f[100001];
int main(){
	scanf("%d",&n);
	vector <int> k;
	for (int i=1;i<=n;i++){
		scanf("%d",&f[i]);
	}
	for (int i=2;i<=n;i++){
		if(m==0){
			if(f[i-1]<f[i]){
				m=1;
			}
			else if(f[i-1]>f[i]){
				m=-1;
			}
			else m=0;
		}
		else{
			if((m==-1&&f[i-1]<f[i])||(m==1&&f[i-1]>f[i])){
				m=0,num++;
			}
		}
		if(i==n) num++;
	}
	cout<<num<<endl;
	return 0;
}

无限序列

#include <bits/stdc++.h>
using namespace std;
int q;
long long sizef[110],num[110];
long long a,b;
inline long long sl(long long v){
	if(v==0){
		return 0;
	}
	int Max=0;
	for (int i=90;i>=1;i--){
		if (sizef[i]<=v){
			Max=i;
			break;
		}
	}
	return num[Max]+sl(v-sizef[Max]);
	
}
int main(){
	sizef[1]=1,sizef[2]=2;
	num[1]=1,num[2]=1;
	for (int i=3;i<=90;i++){
		sizef[i]=sizef[i-1]+sizef[i-2];
		num[i]=num[i-1]+num[i-2];
	}
	scanf("%d",&q);
	for (int i=1;i<=q;i++){
		cin>>a>>b;
		long long h=sl(b)-sl(a-1);
		cout<<h<<endl;
	}
	return 0;
} 

#include <bits/stdc++.h>
using namespace std;
const int N=60;
int n,t,sum,ans;

struct babe{
	int gre,h,pa;
}rabit[N];

bool cmp(babe x,babe y){
	return x.pa<y.pa;
}

bool check(int x){
	sum=0;
	for(int i=1;i<=n;i++){
		rabit[i].pa=rabit[i].h+(x-1)*rabit[i].gre;
	}
	sort(rabit+1,rabit+1+n,cmp);
	for (int i=1;i<=x;i++){
		sum+=rabit[i].pa;
	}
	return sum<=t;
}

int main(){
	scanf("%d%d",&n,&t);
	for (int i=1;i<=n;i++){
		cin>>rabit[i].h;
	}
	for (int i=1;i<=n;i++){
		cin>>rabit[i].gre;
	}
	int l=0,r=n	,mid=0;
	while(l<=r){
		mid=(l+r)/2;
		if(check(mid)) ans=mid,l=mid+1;
		else r=mid-1;
	}
	printf("%d",ans);
	return 0;
} 

深度搜索

#include <bits/stdc++.h>
using namespace std;
int mp[9][9];
vector <char> c[9];
bool hash[10000000];
bool f=false;
char c[9];
struct shit{
	int x,y;
}yep[81];
int k,n;
bool check(int x,int y,int v,int r){
	bool b=false;
	int lie=x,hang=y,qu=(hang/3)*3+lie/3+1;
	if(!hash[9*lie+v+r*81]&&!hash[9*(hang+9)+v+r*81]&&!hash[9*(qu+18)+v+r*81]) b=true;
	return b;
}
void dfs(int i,int t){
	if(i=k-1){
		for (int j=1;j<=9;j++){
			int x=yep[i].x,yep[i].y;
			if(check(x,y,j,t)){
				mp[x][y]=j;
				for (int o=0;o<9;i++){
					for (int l=0;l<9;l++){
						cout<<mp[o][l];
					}
				}
			}
		}
	}
}
int main(){
	while(true){
		for (int i=0;i<9;i++){
			for (int j=0;j<9;j++){
				cin>>c[i+n*9][j];
				int g=int(c[j])-48;
				if(c[j]=='.'){
					yep[k].x=i,yep[k].y=j,k++;
				}
				else if(g>=0&&g<10){
					mp[i][j]=g;
					lie=i,hang=j,qu=(hang/3)*3+lie/3+1;
					hash[9*lie+point+n*81]=true,hash[9*(hang+9)+point+n*81]=true,hash[9*(qu+18)+g+n*81]=true;
				}
				else{
					if(c[j]=='d'){
						f=true;
						break;
					}
				}
			}
			if(f) break;
		}
		if(f) break;
		n++;
	}
	for (int i=0;i<n;i++){
		
	}
}

贪心算法

#include <bits/stdc++.h>
using namespace std;
int n,a,b;
bool m;
const int MaxN=500010;
int h[MaxN];
int main(){
	scanf("%d%d%d",&n,&a,&b);
	for (int i=1;i<=n;i++){
		scanf("%d",&h[i]);
	}
	priority_queue<int> q;
	for (int i=1;i<=n;i++){
		q.push(h[i]);
	}
	int t=0;
	while(q.top()-t*a>0){
		t++;
		int x=q.top();
		q.pop();
		q.push(x-b);
	}
	cout<<t<<endl;
	return 0;
}

#include <bits/stdc++.h>
using namespace std;
const int N=100001;
int n,p;
long long l,h;
struct bei{
	int p;
	long long h;
}tree[N];
bool cmp(bei x,bei y){
	return x.p<y.p;
}
int main(){
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>p>>h;
		tree[i]=(bei){p,h};
	}
	sort(tree,tree+n,cmp);
	for (int i=0;i<n;i++){
		int d=0,h=tree[i].h;
		if(i==0) d=tree[i+1].p-tree[i].p;
		else if(i==n) d=abs(tree[i].p-tree[i-1].p);
		else d=min(abs(tree[i+1].p-tree[i].p),abs(tree[i].p-tree[i-1].p));
		if(d<h) l+=(h-d);
	}
	printf("%d",l);
	return 0;
}

#include <bits/stdc++.h>
using namespace std;
const long long M=1e6+5;
int n,o,tp,Max[M];
//bool hash[M];
stack <int> pain;
int sta[M]; 
//queue <int> bei;
priority_queue <int> l;
int nb[M];
int main(){
	cin>>n;
	/*for (int i=0;i<n;i++){
		cin>>o;
		bei.push(o);
		l.push(o);
	}
	while(!bei.empty()||!pain.empty()){
		if(!bei.empty()){
			if(!pain.empty()&&pain.top()==l.top()){
				printf("%d ",l.top());
				o=pain.top();
				l.pop();
				pain.pop();
				printf("%d ",o);
			}
			else{
				o=bei.front();
				bei.pop();
				pain.push(o);
				hash[o]=true;
				if(o==l.top()){
					//printf("%d ",l.top());
					while(hash[l.top()]&&!l.empty()) l.pop();
					pain.pop();
					printf("%d ",o);
				}
			}
		}
		else{
			o=pain.top();
			pain.pop();
			printf("%d ",o);
		}
	}*/
	for (int i=0;i<n;i++){
		cin>>o;
		nb[i]=o;
	}
	Max[n-1]=nb[n-1];
	for (int i=n-2;i>=0;i--){
		Max[i]=max(Max[i+1],nb[i]);
	}
	o=0;
	for(int i=0;i<n;i++){
		o=nb[i];
		sta[++tp]=o;
		//pain.push(o);
		while(/*pain.top()*/sta[tp]>Max[i+1]){
			printf("%d ",sta[tp--]/*pain.top()*/);
			//pain.pop();
		}
	}
	while(!pain.empty()){
		printf("%d ",sta[tp--]/*pain.top()*/);
		//pain.pop();
	}
	return 0;
}

二分算法

#include <bits/stdc++.h>
using namespace std;
int n,m,l,r,a[100005],s;
bool check(int lim){
	int ans=0,cnt=1;
	for (int i=1;i<=n;i++){
		if(ans+a[i]<=lim) ans+=a[i];
		else ans=a[i],cnt++;
	}
	return cnt<=m;
}
int main(){
	cin>>n>>m;
	for (int i=1;i<=n;i++){
		cin>>a[i];
		r+=a[i];
		l=max(l,a[i]);
	}
	while(l<r){
		int mid=(l+r)>>1;
		if (check(mid)) r=mid;
		else l=mid+1;
	}
	cout<<l<<endl;
	return 0;
}

#include <bits/stdc++.h>
using namespace std;
const long long N=2e5+5;
int t,n;
long long em,s[N],d[N],e[N];
int S(long long x){	
	int ans=0; 
	for (int i=1;i<=n;i++){
		if(s[i]<=x) ans+=(min(x,e[i]) - s[i])/ d[i]+1;
	}
	return ans;
}
void work(){
	scanf("%d",&n);
	for (int i=1;i<=n;i++){
		cin>>s[i]>>e[i]>>d[i];
		em=max(em,e[i]);
	}
	int ans=0;
	if(S(2147483647)%2==0){
		cout<<"There's no weakness."<<endl;
		return;
	}
	else{
		long long l=1,r=em,mid=(l+r)/2;
		while(l<r){
			mid=(l+r)>>1;
			if(S(mid)&1)	r=mid;
			else l=mid+1;
		}
		printf("%d %d\n",l,S(l)-S(l-1));
		return;
	}
}
int main(){
	scanf("%d",&t);
	while(t--){
		work();
	}
	return 0;
} 

宽度搜索

A题 迷宫 求最短时间

#include<bits/stdc++.h>
using namespace std;
int n;
char mp[1001][1001];
int ma[1001][1001];
int sx,sy,tx,ty;
int dx[4]={1,-1,0,0};
int dy[4]={0,0,1,-1};
bool check(int x,int y){
	bool a=false;
	if(x>=1&&x<=n&&y>=1&&y<=n&&ma[x][y]==-1){
		a=true;
	}
	return a;
}
queue <int>qx;
queue <int>qy;
void pu(int x,int y){
	qx.push(x);
	qy.push(y);
	return;
}
int bfs(int x,int y){
	pu(x,y);
	ma[x][y]=0;
	while(!qx.empty()&&!qy.empty()){
		int px=qx.front(),py=qy.front();
		qx.pop(),qy.pop();
		for (int i=0;i<4;i++){
			int vx=px+dx[i],vy=py+dy[i];
			if(check(vx,vy)){
				if(ma[vx][vy]==-1){
					ma[vx][vy]=ma[px][py]+1;
				}
				else{
					ma[vx][vy]=min(ma[vx][vy],ma[px][py]+1);
				}
				pu(vx,vy);
				//if(vx==tx&&vy==ty) return ma[tx][ty];
			}
		}
	}
	return ma[tx][ty];
}
int main(){
	scanf("%d",&n);
	memset(ma,-1,sizeof(ma));
	for (int i=1;i<=n;i++){
		for (int j=1;j<=n;j++){
			cin>>mp[i][j];
			if(mp[i][j]=='1'){
				ma[i][j]=0;
			}
		}
	}
	/*for (int i=1;i<=n;i++){
		for (int j=1;j<=n;j++){
			cout<<mp[i][j];
		}
		cout<<endl;
	}*/
	scanf("%d%d\n%d%d",&sx,&sy,&tx,&ty);
	//printf("%d %d %d %d",sx,sy,tx,ty);
	cout<<bfs(sx,sy)<<endl;
	return 0;
}

2.山峰山谷

#include <bits/stdc++.h>
using namespace std;
int n,k,t;
long long mp[1001][1001];
int ma[1001][1001];
int num1,num2,co,m,l;//co状态,0为山谷,1为山峰,2什么都不是。m判断是否全部等高。 
queue<int> qx;
queue<int> qy;
int dx[8]={1,1,1,0,0,-1,-1,-1};
int dy[8]={1,0,-1,1,-1,1,0,-1};
struct jj{
	int x,y;
}shit[1000000];
void pu(int x,int y){
	qx.push(x),qy.push(y);
	return;
}
bool check(int x,int y){
	bool a=false;
	if(x>=1&&x<=n&&y>=1&&y<=n&&ma[x][y]==0) a=true;
	return a;
}
void bfs(int x,int y){
	co=-1;
	pu(x,y);
	ma[x][y]=k;
	while(!qx.empty()&&!qy.empty()){
		int px=qx.front(),py=qy.front();
		qx.pop(),qy.pop();
		for (int i=0;i<8;i++){
			int vx=px+dx[i],vy=py+dy[i];
			if(check(vx,vy)){
				if(mp[vx][vy]==mp[px][py]){
					pu(vx,vy);
					ma[vx][vy]=k;
				}
				else if(mp[vx][vy]>mp[px][py]){
					if(co==-1) co=0;
					if(co==1) co=2;
				}
				else{
					if(co==-1) co=1;
					if(co==0) co=2;
				}
			}
		}
	}
	if(co==0) num2++;
	if(co==1) num1++;
	cout<<num1<<' '<<num2<<endl;
}
int main(){
	cin>>n;
	for (int i=1;i<=n;i++){
		for (int j=1;j<=n;j++){
			cin>>mp[i][j];
			shit[t].x=i,shit[t].y=j;
			t++;
		}
	}
	l=mp[1][1],k=1;
	for(int i=0;i<n*n;i++){
		if(ma[shit[i].x][shit[i].y]==0) bfs(shit[i].x,shit[i].y),k++;
		if(mp[shit[i].x][shit[i].y]!=l) m=1;
	}
	/*if(m==0){
		num1=1,num2=1;
	}*/
	for (int i=1;i<=n;i++){
		for (int j=1;j<=n;j++){
			cout<<ma[i][j]<<' ';
		}
		cout<<endl;
	}
	//cout<<num1<<' '<<num2<<endl;
	return 0;
}

Hash

课后题

#include <bits/stdc++.h>
using namespace std;
int hash1[50000000];
int hash2[50000000];
long long a0=1,i=1,a1=0;
long long a,b,c;
int main(){
	cin>>a>>b>>c;
	hash1[1]=1;
	while (true){
		a1=(a*a0+a0%b)%c;
		if(i>2000000){
			cout<<-1<<endl;
			break;
		}
		int m=a1;
		if(a1>=50000000){
			m-=50000000;
			if(!hash2[m]) hash2[m]=1;
			else{
				cout<<i<<endl;
				break;
			}
		}
		else{
			if(!hash1[m]) hash1[m]=1;
			else{
				cout<<i<<endl;
				break;
			}
		}
		a0=a1;
		i++;
	}
	return 0;
}

#include <bits/stdc++.h>
using namespace std;
int n;
char mp[101][101];
int jx,jy,fx,fy;
bool check(int x,int y){
	if(x>=1&&x<=n&&y>=1&&y<=n){
		
	}
}
void bfs(int x,int y){
	queue<int> qx;
	queue<int> qy;
	qx.push(x),qy.push(y);
	while(!qx.empty()&&!qy.empty()){
		int px=qx.front(),qx.pop();
		int py=qy.front(),qy.pop();
		int vx=
		if(check())
	}
}
int main(){
	cin>>n;
	for (int i=1;i<=n;i++){
		for (int j=1;j<=n;j++){
			cin>>mp[i][j];
			if(mp[i][j]=='F'){
				fx=i,fy=j;
			}
			else if(mp[i][j]=='J'){
				jx=i,jy=j;
			}
		}
	}
}

字符串处理

1.数字反转

#include <bits/stdc++.h>
using namespace std;
string n;
int sum,k,b;
int main(){
	cin>>n;
	k=1;
	int l=n.size();
	if(n[0]=='-'){
		b=1,k=-1;
	}
	for (int i=l-1;i>=b;i--){
		int u=(int(n[i])-48)*pow(10,i-b);
		sum+=u;
	}
	sum*=k;
	cout<<sum<<endl;
	return 0;
}

并查集

1.

#include <bits/stdc++.h>
using namespace std;
int n,m;
int pre[2000000];
int x[100010],y[100010],z[100010];
int find(int x){
	while(x!=pre[x]){
		x=pre[x];
	}
	return x;
}
void join(int x,int y){
	int fx=find(x),fy=find(y);
	if(fx!=fy){
		pre[fx]=fy;
	}
	return;
}
int main(){
	cin>>n>>m;
	for (int i=1;i<=m;i++){
		cin>>x[i]>>y[i]>>z[i];
		pre[y[i]]=y[i];
		pre[z[i]]=z[i];
	}
	for (int i=1;i<=m;i++){
		int u=find(y[i]),v=find(z[i]);
		if(x[i]==1){
			join(u,v);
		}
		else{
			if(u==v){
				cout<<'Y'<<endl;
			}
			else{
				cout<<'N'<<endl;
			}
		}
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值