1116 Come on! Let’s C (20 分)
Sample Input:
6
1111
6666
8888
1234
5555
0001
6
8888
0001
1111
2222
8888
2222
Sample Output:
8888: Minion
0001: Chocolate
1111: Mystery Award
2222: Are you kidding?
8888: Checked
2222: Are you kidding?
Note1
- 题意 输入num 第一个是Mystery Award 第isprime个是Minon 其他人是Chocolate, query次询问,如果访问过就输出checked 没有就are you kidding
- 思路 map visited记录是否被录入及是否被访问过,s记录应该获得的奖品
Code
#include<iostream>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<string>
#include<fstream>
#include<map>
using namespace std;
const int maxn = 1e4;
bool isprime(int n){
if(n == 1) return 0;
for(int i = 2; i <= sqrt(n); i++){
if(n % i == 0) return 0;
}
return 1;
}
map <string, string> s;
map <string, int> visited;
int main(){
#ifdef _DEBUG
ifstream cin("data.txt");
#endif
int num, query;
cin >> num;
for(int i = 0; i < num; i++){
string temp;
cin >> temp ;
visited[temp] = 1;
if(i == 0) s[temp] = "Mystery Award";
else if(isprime(i + 1)) s[temp] = "Minion";
else s[temp] = "Chocolate";
}
cin >> query;
for(int i = 0; i < query; i++){
string temp;
cin >> temp;
cout << temp << ": ";
if(visited[temp]){
if(visited[temp] == 1) {
cout << s[temp] << endl;
visited[temp] = 2;
}else cout << "Checked" << endl;
}else{
cout << "Are you kidding?" << endl;
}
}
#ifdef _DEBUG
cin.close();
#endif
return 0;
}
1117 Eddington Number (25 分)
Sample Input:
10
6 7 6 9 3 10 8 2 7 8
Sample Output:
6
Note
-
题意 给出num天的骑行英里数,求符合n天大于n英里的最大值
-
思路, 看到数据量觉得可能会超时,所以就用了二分。具体思路为先从大到小排序,mid =… 若符合n天大于n英里, right = mid + 1, 若不符合,left = mid -1,循环退出的条件为left > right,过程中记录符合条件的最大值max
-
其实是一个简单的逻辑题,好惨一男的,其实刷题的目的是为了通过可以练习而达到某种目的,要是像现在这样只想这AC,其实作用不是很大哇 -> 读题 , 题目思考选择方 , 思路确立, 尽量少bug的code
Code1
#include<iostream>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<string>
#include<fstream>
using namespace std;
const int maxn = 1e8;
bool cmp(int a, int b){
return a > b;
}
int a[maxn];
int main(){
#ifdef _DEBUG
ifstream cin("data2.txt");
#endif
int num, max = 0;
cin >> num;
for(int i = 0; i < num; i++){
cin >> a[i];
}
sort(a, a + num, cmp);
int left = 0, right = num -1;
while(left <= right){
int mid = (left + right) / 2;
if(a[a[mid] - 1] <= a[mid]) left = mid + 1;
else {
right = mid -1;
if(a[mid] > max) max = a[mid];
}
}
cout << max;
#ifdef _DEBUG
cin.close();
#endif
return 0;
}
Code2
#include<iostream>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<string>
#include<fstream>
using namespace std;
const int maxn = 1e8;
bool cmp(int a, int b){
return a > b;
}
int a[maxn];
int main(){
#ifdef _DEBUG
ifstream cin("data2.txt");
#endif
int num, max,i = 0;
cin >> num;
for(int i = 0; i < num; i++){
cin >> a[i];
}
sort(a, a + num, cmp);
for( i = 0; i < num; i++){
if(i+1 >= a[i]) break;
}
cout << i ;
#ifdef _DEBUG
cin.close();
#endif
return 0;
}
1118 Birds in Forest (25 分)
Sample Input:
4
3 10 1 2
2 3 4
4 1 5 7 8
3 9 6 4
2
10 5
3 7
Sample Output:
2 10
Yes
No
Note
- 题意:并查集,4张照片,一张里面有temp个元素,询问query次,判断两节点是否一个集合
- 思路 运用路径压缩+按质归并,全当复习基本操作
Code1
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
#include<algorithm>
#include<string>
#include<fstream>
#include<queue>
using namespace std;
const int maxn = 1e5;
int s[maxn] = {-1};
int Find(int x){
if(s[x] < 0) return x;
else return s[x] = Find(s[x]);
}
void Union(int r1, int r2){
if(s[r1] < s[r2]) s[r2] = r1; //r1 is the new root
else{
if(s[r1] == s[r2]) s[r2]--;
s[r1] = r2; // r2 is the new root
}
}
int main(){
#ifdef _DEBUG
ifstream cin("data3.txt");
#endif
int num, max = 0;
cin >> num;
for(int i = 1; i < maxn; i++) s[i] =-1;
for(int i = 1; i <= num; i++){
int tempnum,root;
cin >> tempnum;
for(int j = 0; j <tempnum; j++){
int temp;
cin >> temp;
if(temp > max) max =temp;
if(j == 0) root = temp;
if(j != 0) Union( Find( root), Find( temp));
}
}
int cnt = 0;
for(int i = 1; i <= max; i++)
if(s[i] < 0) cnt++;
int query;
cout << cnt << " " << max << endl;
cin >> query;
for(int i = 0; i < query; i++){
int tempa, tempb, r1, r2;
cin >> tempa >> tempb;
r1 = Find(tempa);
r2 = Find(tempb);
if(r1 == r2) cout << "Yes" << endl;
else cout << "No" << endl;
}
#ifdef _DEBUG
cin.close();
#endif
return 0;
}
1119 Pre- and Post-order Traversals (30 分)
Sample Input 1:
7
1 2 3 4 6 7 5
2 6 7 4 5 3 1
Sample Output 1:
Yes
2 1 6 4 7 3 5
Sample Input 2:
4
1 2 3 4
2 4 3 1
Sample Output 2:
No
2 1 3 4
Note1
- 前序后要序求输出中序,如果不唯一把yes, 改变成No
- To be continued: 总结前中后三推二的代码
Code
#include<iostream>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<string>
#include<fstream>
using namespace std;
#define INF 1e9
const int maxn = 1e3;
int post[maxn] = {0}, flag = 1;
int pre[maxn] = {0};
vector <int> intern;
void ToInter(int preLeft, int preRight, int postLeft, int postRight) {
if(preLeft == preRight) {
intern.push_back(pre[preLeft]);
return;
}
if (pre[preLeft] == post[postRight]) {
int i = preLeft + 1;
while (i <= preRight && pre[i] != post[postRight-1]) i++;
if (i - preLeft > 1)
ToInter(preLeft + 1, i - 1, postLeft, postLeft + (i - preLeft - 1) -1);
else flag = 0;
intern.push_back(post[postRight]);
ToInter(i, preRight, postLeft + (i - preLeft - 1), postRight - 1);
}
}
int main(){
#ifdef _DEBUG
ifstream cin("data4.txt");
#endif
int num;
cin >>num;
for(int i = 0; i <num; i++) cin >> pre[i];
for(int i = 0; i <num; i++) cin >> post[i];
ToInter(0, num - 1, 0, num - 1);
if(flag == 1) cout << "Yes" << endl;
else cout << "No" << endl;
printf("%d", intern[0]);
for (int i = 1; i < intern.size(); i++) printf(" %d", intern[i]);
cout << endl;
#ifdef _DEBUG
cin.close();
#endif
return 0;
}
//void inter(int root, int start, int finish, int index){
// if(start > finish) return ;
// int i = finish;
// while(i - 1 >= start && pre[i] != post[root - 1]) i--;
// if(i - 1 >= start && pre[i - 1] == root) flag = 1;
// first.push_back({index, post[root]});
// inter(root - 1, i + 1, finish, 2 * index + 2);
// inter(root - 1 - finish + i, start, i - 1, 2 * index + 1);
//}