赞
踩
A : 打酱油
问题描述
小明带着N元钱去买酱油。酱油10块钱一瓶,商家进行促销,每买3瓶送1瓶,或者每买5瓶送2瓶。请问小明最多可以得到多少瓶酱油。
输入格式
输入的第一行包含一个整数N,表示小明可用于买酱油的钱数。N是10的整数倍,N不超过300。
输出格式
输出一个整数,表示小明最多可以得到多少瓶酱油。
样例1
输入
40
输出
5
样例说明
把40元分成30元和10元,分别买3瓶和1瓶,其中3瓶送1瓶,共得到5瓶。
样例2
输入
80
输出
11
样例说明
把80元分成30元和50元,分别买3瓶和5瓶,其中3瓶送1瓶,5瓶送2瓶,共得到11瓶。
代码:
#include<iostream> using namespace std; int main(){ int N=0,M=0; cin>>N; while(N>=50){ N-=50; M+=7; } while(N>=30){ N-=30; M+=4; } while(N>=10){ N-=10; M+=1; } cout<<M<<endl; return 0; }
B : 最小差值
问题描述
给定n个数,请找出其中相差(差的绝对值)最小的两个数,输出它们的差值的绝对值。
输入格式
输入第一行包含一个整数n。 第二行包含n个正整数,相邻整数之间使用一个空格分隔。
输出格式
输出一个整数,表示答案。
样例1
输入
5 1 5 4 8 20
输出
1
样例说明
相差最小的两个数是5和4,它们之间的差值是1。
样例2
输入
5 9 3 6 1 3
输出
0
样例说明
有两个相同的数3,它们之间的差值是0.
数据规模和约定
对于所有评测用例,2 ≤ n ≤ 1000,每个给定的整数都是不超过10000的正整数
代码:
#include<iostream> using namespace std; int main(){ int n =0, x = 0, result = 0; cin>>n; int *num = new int[n]; for(int i = 0; i < n; i++) cin>>num[i]; result =abs(num[0] - num[1]); for(int i = 0; i < n; i++){ for(int j = 0; j < i; j++){ x = num[i] - num[j]; x = abs(x); result = min(x,result); } } cout<<result; return 0; }
问题描述
给定 n 个不同的整数,问这些数中有多少对整数,它们的值正好相差 1。
输入格式
输入的第一行包含一个整数 n,表示给定整数的个数。 第二行包含所给定的n个整数。
输出格式
输出一个整数,表示值正好相差1的数对的个数。
样例输入
6 10 2 6 3 7 8
样例输出
3
样例说明
值正好相差1的数对包括 (2, 3), (6, 7), (7, 8)。
评测用例规模与约定
1≤n≤1000,给定的整数为不超过 10000的非负整数。
代码:
#include<bits/stdc++.h> using namespace std; int main(){ int n; cin>>n; int cnt = 0; int *num = new int[n]; for(int i = 0; i < n; i++){ cin>>num[i]; } //O(n) for(int i = 0; i < n; i++){ for(int j = i + 1; j < n; j++){ if(num[i] - num[j] == 1 || num[j] - num[i] ==1){ cnt++; } } } //O(n^2) cout<<cnt<<endl; return 0; }
B : 门禁系统
问题描述
涛涛最近要负责图书馆的管理工作,需要记录下每天读者的到访情况。每位读者有一个编号,每条记录用读者的编号来表示。给出读者的来访记录,请问每一条记录中的读者是第几次出现。
输入格式
输入的第一行包含一个整数n,表示涛涛的记录条数。 第二行包含n个整数,依次表示涛涛的记录中每位读者的编号。
输出格式
输出一行,包含n个整数,由空格分隔,依次表示每条记录中的读者编号是第几次出现。
样例输入
5 1 2 1 1 3
样例输出
1 1 2 3 1
评测用例规模与约定
1≤n≤1000,读者的编号为不超过 n的正整数。
代码:
#include<bits/stdc++.h> using namespace std; int main(){ int n,a; int num[1001] = {0}; cin>>n; for(int i = 0; i < n; i++){ cin>>a; num[a]++; cout<<num[a]<<" "; } //O(n) return 0; }
C : 桶装数字
问题描述
yhf有 n个桶,每个桶里都装着一些数字(一个或多个),所有的数字总共有 m个。这天,lzh把yhf所有的桶全打翻了,数字洒了一地!所幸,每个数字都有它所在的桶的标记。yhf希望恢复所有的桶,但是他还要刷考研题目,于是他拜托你来完成这个任务。 由于yhf能在一秒内完成一套考研数学题,因此他希望你的程序能在一秒内得出结果。
输入格式
第一行输入两个整数 n,m,第二行到第 m+1 行,每行两个整数 x,t,分别表示这个数字和它所在的桶。 保证每个桶至少含有一个数字。
输出格式
输出 n 行,若第 i个桶含有 ki个数字,则第 i行输出 ki个整数,表示这个桶内的数字。注意:输出每个桶的数字时应按升序排序输出。
样例输入
2 5 3 1 2 2 2 1 3 2 1 2
样例输出
2 3 1 2 3
评测用例规模与约定
对于60%的数据,1≤n,m≤1000 对于100%的数据,1≤n,m≤10^5,0≤x≤10^9,1≤t≤n
代码:
#include<bits/stdc++.h> using namespace std; int main(){ int m,n;//n个桶,m个数字 int a,b; int cnt[100001] = {0}; int num1[100001] = {0};//数字 int num2[100001] = {0};//桶 vector<int> v[100001]; cin>>n>>m; for(int i = 0; i < m; i++){ cin>>num1[i]; cin>>num2[i]; v[num2[i]].push_back(num1[i]); //O(1) cnt[num2[i]]++; }// O(n) for(int i = 1; i <= n; i++){ sort(v[i].begin(),v[i].begin()+cnt[i]); //O(nlogn) for(vector<int>::iterator it = v[i].begin();it!=v[i].end();it++) cout<<*it<<" "; //O(n) cout<<endl; } //O(n^2*logn) return 0; }
D : 笔记本
问题描述
为了复习考研英语,yhf开始背单词。 yhf有一个笔记本,一开始是空的。当yhf遇到一个不认识的单词时,他会先查找笔记本,如果笔记本上没有,他就会先在互联网上查找这个单词,然后记在笔记本上。当yhf认为他已经熟记一个单词时,他会将这个单词在笔记本上擦掉(如果笔记本上没有就不用擦了)。yhf有时也会关心他的笔记本上记了多少单词,他会将笔记本上的单词按照字典序升序读一遍。 这天,yhf发现他的笔记本已经记满了单词,他决定用程序来实现笔记本的功能。但考虑到编写程序消耗的时间可以多背几千个单词,他决定把这个认为交给你。
输入格式
输入第一行包含一个整数 m,接下来有 m 行,每一行有一个整数 op,表示你的程序应执行哪种操作,具体如下
op=1,后接一个单词,表示查找这个单词;如果笔记本中没有这个单词,则将单词写进笔记本
op=2,后接一个单词,表示删除这个单词;如果笔记本中没有这个单词,则无需进行操作
op=3,表示按字典序通读整个笔记本
输出格式
输出 m行,每一行表示输入的操作对应的输出,具体如下
op=1,如果笔记本中有这个单词,输出found
,否则输出write
op=2,如果笔记本中有这个单词,输出erased
,否则输出not found
op=3,在一行内按字典序升序输出所有单词,中间用空格隔开
样例输入
8 1 problem 1 problem 2 problem 1 problem 2 acm 1 pro 1 acm 3
样例输出
write found erased write not found write write acm pro problem
评测用例规模与约定
对于60%的数据,m≤100。 对于100%的数据,m≤10^5,单词长度∣s∣≤10 且由小写字母构成。 保证操作3的次数不超过3次。
代码:
#include<bits/stdc++.h> using namespace std; //set有序 int main(){ int m, op, num = 0; string str; bool flag = 1; cin>>m; set<string> s; for(int i = 0; i < m; i++){ cin>>op; switch (op){ case 1: cin>>str; if(s.count(str)){ //O(logn) cout<<"found"<<endl; } else{ s.insert(str); //O(logn) num++; cout<<"write"<<endl; } break; case 2: cin>>str; if(s.find(str) != s.end()){ //O(logn) cout<<"erased"<<endl; s.erase(str); //O(logn) num--; } else cout<<"not found"<<endl; break; case 3:{ vector<string> v; for(set<string>::iterator it = s.begin(); it != s.end(); it++) cout<<*it<<" "; //set有序 cout<<endl; break; } default: break; } } return 0; }
A : 游戏
问题描述
有n个小朋友围成一圈玩游戏,小朋友从1至n编号,2号小朋友坐在1号小朋友的顺时针方向,3号小朋友坐在2号小朋友的顺时针方向,……,1号小朋友坐在n号小朋友的顺时针方向。 游戏开始,从1号小朋友开始顺时针报数,接下来每个小朋友的报数是上一个小朋友报的数加1。若一个小朋友报的数为k的倍数或其末位数(即数的个位)为k,则该小朋友被淘汰出局,不再参加以后的报数。当游戏中只剩下一个小朋友时,该小朋友获胜。 例如,当n=5, k=2时: 1号小朋友报数1; 2号小朋友报数2淘汰; 3号小朋友报数3; 4号小朋友报数4淘汰; 5号小朋友报数5; 1号小朋友报数6淘汰; 3号小朋友报数7; 5号小朋友报数8淘汰; 3号小朋友获胜。
给定n和k,请问最后获胜的小朋友编号为多少?
输入格式
输入一行,包括两个整数n和k,意义如题目所述。
输出格式
输出一行,包含一个整数,表示获胜的小朋友编号。
样例1
输入
5 2
输出
3
样例2
输入
7 3
输出
4
数据规模和约定
对于所有评测用例,1 ≤ n ≤ 1000,1 ≤ k ≤ 9。
笔记:
vector 的相关时间复杂度
pop_back(); //O(1) erase(); //O(n) push_back(); //O(1) insert(); //O(n) 访问 O(1)
代码:
#include<bits/stdc++.h> using namespace std; int main(){ int n = 0, k = 0; int nums = 0, j = 0; scanf("%d%d",&n,&k); vector<int> v; int i = 1;//用于计数 if(k == 1){ cout<<n<<endl; return 0; } for( ; i <= n; i ++){ if(i%k == 0 || i%10 == k) continue; else{ v.push_back(i); //插入N个元素, 则会引发lgN次的内存扩充,O(1) nums++; } } //O(n) while(nums > 1){ if(i%k == 0 || i%10 == k){ v.erase(v.begin()+j ); // erase删除的复杂度为O(n) nums--; j = j%nums; } else{ j = (j + 1)%nums; } i++; } //O(N^2) printf("%d\n",v[0]); return 0; }
问题描述
近来,跳一跳这款小游戏风靡全国,受到不少玩家的喜爱。 简化后的跳一跳规则如下:玩家每次从当前方块跳到下一个方块,如果没有跳到下一个方块上则游戏结束。 如果跳到了方块上,但没有跳到方块的中心则获得1分;跳到方块中心时,若上一次的得分为1分或这是本局游戏的第一次跳跃则此次得分为2分,否则此次得分比上一次得分多两分(即连续跳到方块中心时,总得分将+2,+4,+6,+8…)。 现在给出一个人跳一跳的全过程,请你求出他本局游戏的得分(按照题目描述的规则)。
输入格式
输入包含多个数字,用空格分隔,每个数字都是1,2,0之一,1表示此次跳跃跳到了方块上但是没有跳到中心,2表示此次跳跃跳到了方块上并且跳到了方块中心,0表示此次跳跃没有跳到方块上(此时游戏结束)。
输出格式
输出一个整数,为本局游戏的得分(在本题的规则下)。
样例输入
1 1 2 2 2 1 1 2 2 0
样例输出
22
数据规模和约定
对于所有评测用例,输入的数字不超过30个,保证0正好出现一次且为最后一个数字。
代码:
#include<bits/stdc++.h> using namespace std; int main(){ int score = 0; int temp = 1; int nums; while(scanf("%d",&nums) && nums != 0){ if(nums == 1){ temp = 1; score += temp; } else{ if(temp == 1){ temp = 2; score += temp; } else{ temp += 2; score += temp; } } } //O(N) printf("%d\n",score); return 0; }
问题描述
小H有一个奇怪的电梯,电梯可以根据需要停在每个楼层,每个楼层上都对应一个数字K_i(0 <= K_i <= N),该电梯只有两个按钮:“UP"和"DOWN”。在第i层楼,如果按下"UP"按钮,电梯将移动到i+K_i层;如果按下"DOWN",电梯将移动到i-K_i层。当然,电梯有一个移动的范围,不能高于N且不能低于1。例如,有一个5层楼的建筑物,k_1 = 3,k_2 = 3,k_3 = 1,k_4 = 2,k_5 =5。从一楼开始,按"UP"按钮,将上升到四楼,如果按"DOWN"按钮,电梯将无法移动,因为它不能下降到-2楼。 现在问题来了:小H想从A层移动到B层,他至少要按几次"UP"或"DOWN"按钮,你能帮帮他嘛?
输入格式
输入包含多个测试用例。每个测试用例包含两行。 第一行包含上述三个整数N,A,B(1 <= N,A,B <= 200),第二行包含N个整数k_1,k_2,.... k_n。 若读取到单个0,则表示输入结束。
输出格式
对于每个测试用例,输出一个整数表示最少按下"UP"或"DOWN"按钮的次数,若无法到达B层,请输出"-1"。每个测试用例的输出占一行。
样例输入
5 1 5 3 3 1 2 5 0
样例输出
3
数据规模和约定
1<=N,A,B<=200,0<=k_i<=N
提示
隐式图问题
代码:
#include<bits/stdc++.h> using namespace std; map<int, int> father; queue<int> q; void check(int x, int y){ if(father.find(y) == father.end()){//y没有到达过 O(logn) q.push(y); //O(logn) father[y] = x; //y的上一个状态是x } }//O(logn) void bfs(int A, int B, int N, int *k){ int now = A; q.push(now); //O(1) while(!q.empty()){ now = q.front(); //O(1) q.pop(); //O(1) if(now == B){ int u = now; stack<int> temp; while(u != A){ temp.push(u); u = father[u]; } // temp.push(u); printf("%d\n",temp.size()); return; } if(now + k[now] <= N) check(now, now + k[now]); if(now - k[now] >= 1) check(now, now - k[now]); } printf("-1\n"); } int main(){ int N,A,B; while(scanf("%d",&N) && N!=0){ scanf("%d",&A); scanf("%d",&B); int *k = new int[N+1]; for(int i = 1; i <= N; i++){ scanf("%d",&k[i]); //O(N) } while(!q.empty()) q.pop(); //清空队列O(n) father.clear(); bfs(A,B,N,k); delete k; } //O(N^2) return 0; }
问题描述
已知n个整数 x_1,x_2,…,x_n 和1个整数k(k<n)。从n个整数中任选k个整数相加,可分别得到一系列的和。例如当n=4,k=3,x_1=3,x_2=7,x_3=12,x_4=19时,可得全部的组合与它们的和为:
3+7+12=223+7+12=22 3+7+19=293+7+19=29 7+12+19=387+12+19=38 3+12+19=343+12+19=34
现在,要求你计算出和为素数共有多少种。
例如上例,只有一种的和为素数:3+7+19=293+7+19=29。
输入格式
输入包含两行 第一行两个数n,k 第二行n个数依次表示x_i
输出格式
一个整数,表示合法的组合数
样例输入
4 3 3 7 12 19
样例输出
1
数据规模和约定
1<=k<n<=20 1<=x_i<=5000000
提示
素数的判定方法
bool prime(int n) { if(n==1) return false; if (n==2) return true; for(int i=2;i*i<=n;i++) if (n%i==0) return false; return true; }
代码:
#include<bits/stdc++.h> using namespace std; bool prime(int n){ if (n==1) return false; if (n==2) return true; for(int i=2;i*i<=n;i++) if (n%i==0) return false; return true; } int main(){ int n,k,cnt = 0; scanf("%d%d",&n,&k); int *a = new int[n]; for(int i = 0; i < n; i++) scanf("%d",&a[i]); //O(n) int *b = new int[n]; for(int i = 0, sum = pow(2,n); i< sum; i++){ int nums = 0; int result = 0; int temp = i; result = 0; for(int j = 0; j < n; j++){ b[j] = temp%2;//二进制表示每个输入的数取或不取 temp /=2; } //O(N) for(int j = 0; j < n; j++) nums += b[j]; if(nums == k){ for( int j = 0; j < n; j++) result += b[j]*a[j]; if (prime(result)) cnt ++; //O(logn) } }//O(2^n*n) printf("%d\n",cnt); return 0; }
问题描述
小H收集到一些形状特殊的棋盘,她想在棋盘上面摆放棋子(棋子都是相同的)。她希望摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,你能帮她求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案数C嘛?
输入格式
输入含有多组测试数据。 每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目。 当为-1 -1时表示输入结束。 随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。 注意只有#棋盘区域可以摆放棋子。
输出格式
对于每一组数据,给出一行输出,输出摆放的方案数目C (数据保证C<2^31)
样例输入
2 1 #. .# 4 4 ...# ..#. .#.. #... -1 -1
样例输出
2 1
数据规模和约定
1<=k<=n<=8
代码:
#include<bits/stdc++.h> using namespace std; int nums = 0; int vis[9] = {0}; //记录数字是否被使用 bool a[9][9]; char c; void permutation(int x, int y, int n, int k){ if( y == k){ nums++; return; } for(int i = x; i < n; i++) for(int j = 0; j < n; j++){ if(vis[j] == 0 && a[i][j]) { //此列未被放置且此位置可以放置 vis[j] = 1; permutation(i+1,y+1,n,k); vis[j] = 0; } } } int main(){ int n,k; while(scanf("%d%d",&n,&k) && n != -1 && k != -1){ int i = 0; for (int j = 0; j < n; j++){ for (int i = 0; i < n; i++){ cin >> c; if (c == '#')//棋盘区域,可以摆放棋子 a[i][j] = 1; else a[i][j] = 0; } }//O(n^2) for(int i = 0; i <= n; i++){ //每一组数据 nums = 0; permutation(0,0,n,k); } cout<<nums<<endl; } return 0; }
题目描述
滨海公园旁边新铺了一条路,把这条路分成n段,依次编号为1…n。为了防止游客把垃圾扔到海里,war要在路上放一些垃圾桶声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。