几个有意思的题目
1、辉辉的日程表
也不知道各位大佬是怎么做的,我就傻傻地用区间覆盖,有事的时间区间直接标记为1。
球带,在线等高级NOI级别的专业做法。
#include <stdio.h> #include <string.h> int a[34]; int main() { int n,j,k,i; scanf("%d",&n); for(k=1;k<=n;k++) { int l,r,f=0; scanf("%d%d",&l,&r); r--; for(i=l;i<=r;i++) if(a[i]) { f=1; break; } if(!f) { for(i=l;i<=r;i++) a[i]=1; printf("Y\n"); } else printf("N\n"); } return 0; }
2、二进制加法
模拟进位即可,注意最高位可能要判断是否要加一位。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int n; char c[123]; int c1[123],c2[123],ans[123]; int main() { scanf("%d",&n); while(n--) { scanf("%s",c+1); memset(c1,0,sizeof(c1)); memset(c2,0,sizeof(c2)); memset(ans,0,sizeof(ans)); int n1=strlen(c+1); for(int i=n1;i>=1;i--) c1[n1-i+1]=c[i]-'0'; scanf("%s",c+1); int n2=strlen(c+1); for(int i=n2;i>=1;i--) c2[n2-i+1]=c[i]-'0'; int ll=max(n1,n2); int ov=0; for(int i=1;i<=ll;i++) { ans[i]=c1[i]+c2[i]+ov; if(ans[i]==2) ans[i]=0,ov=1; else if(ans[i]==3) { ans[i]=1; ov=1; } else ov=0; } if(ov) ans[++ll]=1; for(int i=ll;i>=1;i--) printf("%d",ans[i]); printf("\n"); } return 0; }
3、危情24小时
题目怎么说怎么做,注意那个体温总变化幅度是时时监测的。
#include <iostream> #include <cstring> #include <algorithm> #include <cstdio> #include <cmath> using namespace std; struct point { int tt; int t; }pa[23]; int n,nn; double pp[8][23],Min[23],Max[23]; int ans[243][4],vis[23]; inline bool ok(int i,int j) { if((pp[j][i]>=41 || pp[j][i]<=33) && (pp[j-1][i]>=41 || pp[j-1][i]<=33) && (pp[j-2][i]>=41 || pp[j-2][i]<=33)) return 1; return 0; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) Min[i]=9999; for(int j=0;j<=6;j++) { for(int i=1;i<=n;i++) { scanf("%lf",&pp[j][i]); Min[i]=min(Min[i],pp[j][i]); Max[i]=max(Max[i],pp[j][i]); if(vis[i]) continue; if(pp[j][i]>=42 || pp[j][i]<=32 || (j!=0 && abs(pp[j][i]-pp[j-1][i])>=2) || Max[i]-Min[i]>=4) { vis[i]=1; ans[++nn][1]=i; ans[nn][2]=j; continue; } if(j>=2 && ok(i,j)) { vis[i]=1; ans[++nn][1]=i; ans[nn][2]=j; continue; } } } for(int i=1;i<=n;i++) { if(vis[i]) continue; double ave=0,Min=1234,Max=0; for(int j=0;j<=6;j++) ave+=pp[j][i]; ave/=7; if(ave>=40 || ave<=34 || Max-Min>=4) ans[++nn][1]=i,ans[nn][2]=6; } for(int i=1;i<=nn;i++) { printf("%d %d:00\n",ans[i][1],(ans[i][2])*4); } if(nn==0) printf("None"); return 0; }
4、全排列
这是一个很明显的搜索,(虽然第一眼看见“此题严格使用C语言”的时候不是很开心)
每一步从小到大尝试所有的字母,递归下一步。
#include <stdio.h> #include <string.h> char c[7],ans[7]; int vis[7],n; void dfs(int tt) { int i; if(tt==n+1) { for(i=1;i<=n;i++) printf("%c",ans[i]); printf("\n"); return; } for(i=1;i<=n;i++) if(!vis[i]) { ans[tt]=c[i]; vis[i]=1; dfs(tt+1); vis[i]=0; } return; } int main() { scanf("%s",c+1); n=strlen(c+1); dfs(1); return 0; }
5、最佳凑单
估计老师想考搜索,但是鉴于总共不超过10个物体,为啥不枚举呢?
10个物体的所有状态总共不超过2^11-1种情况,1秒内可以运算出。
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> using namespace std; int n,st,s; int a[12]; inline int get() { int res=0; for(int i=1;i<=n;i++) if(st&(1<<(i-1))) res+=a[i]; return res; } int main() { scanf("%d%d",&n,&s); int ans=0; for(int i=1;i<=n;i++) scanf("%d",&a[i]),ans+=a[i]; if(ans<s) { printf("0"); return 0; } st=((1<<(n+1))-1); ans=1e9; while(st>0) { int tmp=get(); if(tmp>=s && tmp<ans) ans=tmp; st--; } printf("%d",ans); return 0; }