普及组测试题
疑惑??老师是不是出错题了(水)
消失的数字(number)
Time Limit:1000ms Memory Limit:128MB
题目描述
rsy拥有n个数,这n个数分别是a1,a2,…,an。
后来出现了一个熊孩子zhw,用橡皮擦去了其中若干个数字,并且打乱了剩下的数字。rsy赶到现场后只剩下了m个数字b1,b2,…,bm,她想知道哪些数字被擦去了。
现在你需要告诉rsy被擦去的n-m个数是什么。
输入格式(number.in)
第一行一个数n,第二行n个数ai,表示一开始的数字。
第三行一个数m,第四行m个数bi,表示被擦去后的数字。
输出格式(number.out)
一行n-m个数,从小到大输出所有被擦去的数字。
输入样例
5
1 3 5 7 8
3
3 5 8
输出样例
1 7
数据范围
对于30%的数据n<=1000,ai与bi都是有序的。
对于60%的数据n<=100000,ai与bi都是有序的。
对于80%的数据n<=100000,ai,bi<=n。
对于100%的数据n<=100000,1<=ai,bi<=10^9。
soluction:
map<long long,int>MAP
可以使用STL——map水一下这道题
>>map
#include<iostream> #include<cstdio> #include<iomanip> #include<algorithm> #include<map> using namespace std; int a[1000005],x,b[1000005],tot,n,m; map<long long,int>Q; int main() { cin>>n; for(int i=1;i<=n;i++){cin>>a[i];Q[a[i]]++;} cin>>m; for(int i=1;i<=m;i++){cin>>x;Q[x]--;} for(int i=1;i<=n;i++){if(Q[a[i]]!=0)Q[a[i]]--,b[++tot]=a[i];} sort(b+1,b+1+n-m); for(int i=1;i<=n-m;i++) cout<<b[i]<<" "; return 0; }
>>std 使用两个队列乱搞,使用一个指针x,指向较短的队列
#include <cmath> #include <cstdio> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; int n,m,i,X,a[100005],b[100005]; int cmp(int i,int j) {return i<j;} int main() { freopen("number.in","r",stdin); freopen("number.out","w",stdout); scanf("%d",&n); for (i=1; i<=n; i++) scanf("%d",&a[i]); scanf("%d",&m); for (i=1; i<=m; i++) scanf("%d",&b[i]); sort(a+1,a+n+1,cmp); sort(b+1,b+m+1,cmp); X=1; for (i=1; i<=n; i++) { if (a[i]==b[X]) X++; else printf("%d ",a[i]); } return 0; }
一道数论好题(math)
Time Limit:1000ms Memory Limit:128MB
题目描述
rsy最近在研究欧几里得算法,不会的同学可以去看下课件以及代码……
现在她想到了一个新的问题,求k个数的最大公约数!
事实上这个问题仍然很简单。所以rsy想强化一下,她觉得最大公约数等于1就不是很有趣了。因此她想在n个数中找最多的数,使得它们的最大公约数不等于1。
现在rsy想知道,能找最多多少个数。
输入格式(math.in)
第一行一个数n。
第二行n个数ai。
输出格式(math.out)
一个数表示答案。
输入样例
5
2 3 4 5 6
输出样例
3
数据范围
对于30%的数据n<=5。
对于50%的数据n<=20。
对于80%的数据n<=1000,ai<=1000。
对于100%的数据1<=n<=100000,1<=ai<=100000,数据几乎是随机的。
soluction:
埃拉托斯尼筛法
#include<iostream> #include<cstdio> #include<iomanip> #include<algorithm> #include<map> #define N 1000100 #define max(a,b) (a>b?a:b) #define ll long long using namespace std; int n,a[N],prime[N],v[N],tot,maxn,sum=0; map<ll,int>M; void altsn(){ for(ll i=2;i<=maxn;i++){ if(v[N]==0){ prime[++tot]=i; }int tp=0; for(ll j=i;j<=maxn;j+=i){ if(j<=maxn&&j>=0){ prime[j]=1; if(M[j]>=1){tp+=M[j];} } }sum=max(tp,sum); } } int main() { freopen("math.in","r",stdin);freopen("math.out","w",stdout); cin>>n; for(int i=1;i<=n;i++){ cin>>a[i]; maxn=max(a[i],maxn);M[a[i]]++; }altsn(); cout<<sum; fclose(stdin);fclose(stdout); return 0; }
std
#include <cmath> #include <cstdio> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; int n,A,a[1000005],now,MAX,i,j; int main() { freopen("math.in","r",stdin); freopen("math.out","w",stdout); scanf("%d",&n); for (i=1; i<=n; i++) { scanf("%d",&A); a[A]++; } for (i=2; i<=1000000; i++) { now=0; for (j=i; j<=1000000; j+=i) now+=a[j]; MAX=max(MAX,now); } cout<<MAX; return 0; }
扫雷(mine)
Time Limit:1000ms Memory Limit:128MB
题目描述
rsy最近沉迷于一款叫扫雷的游戏。
这个游戏是这样的。一开始网格上有n*m个位置,其中有一些位置有雷。每次rsy可以左键点击一个方块,此时若这个方块是雷,则rsy被炸,游戏结束,否则如果这个位置周围8格有x个雷,则会显示数字x。特别地,当x=0时,系统会自动左键点击附近8个位置。(此时附近8个位置一定没有雷,假如附近8个位置仍存在x=0,则继续往外扩展)想要更进一步获得关于题目的信息,打开程序->附近->游戏->扫雷或者直接打开下发的可执行文件。
或者rsy右键点击一个位置,标注这个位置是雷。
不幸的是,她鼠标不能左右键同时点击,因此只需考虑她左键点击与右键点击就可以了。
注意游戏胜利的条件是所有非雷的位置都被左键点击到。(特别地,当一开始时n*m个位置都是雷时,LYK自动获得胜利)
rsy从网上下载了金手指,很轻易地就掌握了所有雷所在的位置。rsy想通过最少的点击次数获得胜利(这里的点击次数不包括系统自动点击)。于是他来请求你的帮助。
输入格式(mine.in)
第一行两个数n,m。
接下来n行,每行m个数ai,j,表示这个矩阵。若ai,j=’*’则表示这个位置是雷,若ai,j=’.’则表示不是雷。
输出格式(mine.out)
一个数表示答案。
输入样例
3 3
..*
...
..*
输出样例
2
对于30%的数据n=1;
对于另外20%的数据n,m<=3;
对于再另外20%的数据*大致占矩阵的2/3且数据随机。
对于100%的数据n,m<=1000。
Hint:
适度游戏益脑,沉迷游戏伤身。
solution:BFS
下面程序中有些许不必要的东西:比如可以不用记录每个点的感应地雷值
#include<iostream> #include<cstdio> #include<iomanip> #include<algorithm> #include<map> using namespace std; int n,m,ans,bom,que[1000000][2]; int a[1005][1005]; int mx[9]={0,0,0,1,1,1,-1,-1,-1}, my[9]={0,1,-1,0,1,-1,0,1,-1}; bool vis[1005][1005]; void bfs(int xx,int yy){ int h=1,t=1;que[1][0]=xx;que[1][1]=yy;vis[xx][yy]=1; while(h<=t){ int x=que[h][0],y=que[h][1]; for(int i=1;i<=8;i++){ int tx=mx[i]+x,ty=my[i]+y; if(tx>=1&&tx<=n&&ty>=1&&ty<=m&&a[tx][ty]!=-1){ if(a[tx][ty]==0&&vis[tx][ty]==0){ que[++t][0]=tx;que[t][1]=ty; } }vis[tx][ty]=1; }++h; } } int main() { freopen("mine.in","r",stdin);freopen("mine.out","w",stdout); cin>>n>>m; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ char x;cin>>x; if(x==‘*‘) a[i][j]=-1,++bom; } }for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ if(a[i][j]==-1){ if(a[i-1][j]!=-1) ++a[i-1][j]; if(a[i-1][j-1]!=-1) ++a[i-1][j-1]; if(a[i-1][j+1]!=-1) ++a[i-1][j+1]; if(a[i+1][j]!=-1) ++a[i+1][j]; if(a[i+1][j-1]!=-1) ++a[i+1][j-1]; if(a[i+1][j+1]!=-1) ++a[i+1][j+1]; if(a[i][j+1]!=-1) ++a[i][j+1]; if(a[i][j-1]!=-1) ++a[i][j-1]; } } } for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ if(vis[i][j]==0&&a[i][j]==0){ bfs(i,j);++ans; } } }for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ if(vis[i][j]==0&&a[i][j]!=-1) ++ans; } }cout<<ans; fclose(stdin);fclose(stdout); return 0; }
std:BFS
#include <cmath> #include <cstdio> #include <cstdlib> #include <iostream> #include <algorithm> #include <string> #include <cstring> using namespace std; int a[1005][1005],k,sum,X,n,m,i,j,sx[1000005],sy[1000005],L,R; bool v[1005][1005]; const int F1[8]={-1,-1,-1,0,0,1,1,1}; const int F2[8]={-1,0,1,-1,1,-1,0,1}; char s[1005][1005]; void dfs(int x,int y) { L=0; R=1; sx[1]=x; sy[1]=y; while (L!=R) { L++; if (!a[sx[L]][sy[L]] && s[sx[L]][sy[L]]==‘.‘) for (int i=0; i<8; i++) if (!v[F1[i]+sx[L]][F2[i]+sy[L]]) { v[F1[i]+sx[L]][F2[i]+sy[L]]=true; sx[++R]=F1[i]+sx[L]; sy[R]=F2[i]+sy[L]; } } } int main() { freopen("mine.in","r",stdin); freopen("mine.out","w",stdout); scanf("%d%d",&n,&m); for (i=0; i<=n+1; i++) for (j=0; j<=m+1; j++) v[i][j]=true; for (i=1; i<=n; i++) for (j=1; j<=m; j++) v[i][j]=false; for (i=1; i<=n; i++) scanf("%s",s[i]+1); for (i=1; i<=n; i++) for (j=1; j<=m; j++) if (s[i][j]==‘.‘) { X=0; for (k=0; k<8; k++) if (s[i+F1[k]][j+F2[k]]==‘*‘) X++; a[i][j]=X; } for (i=1; i<=n; i++) for (j=1; j<=m; j++) if (!a[i][j] && s[i][j]==‘.‘ && !v[i][j]) {sum++; v[i][j]=true; dfs(i,j);} for (i=1; i<=n; i++) for (j=1; j<=m; j++) if (s[i][j]==‘.‘ && !v[i][j]) sum++; cout<<sum; return 0; }