A1116 A1117 A1118 A1119 模拟练习4

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

  1. 题意 输入num 第一个是Mystery Award 第isprime个是Minon 其他人是Chocolate, query次询问,如果访问过就输出checked 没有就are you kidding
  2. 思路 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

  1. 题意 给出num天的骑行英里数,求符合n天大于n英里的最大值

  2. 思路, 看到数据量觉得可能会超时,所以就用了二分。具体思路为先从大到小排序,mid =… 若符合n天大于n英里, right = mid + 1, 若不符合,left = mid -1,循环退出的条件为left > right,过程中记录符合条件的最大值max

  3. 其实是一个简单的逻辑题,好惨一男的,其实刷题的目的是为了通过可以练习而达到某种目的,要是像现在这样只想这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

  1. 题意:并查集,4张照片,一张里面有temp个元素,询问query次,判断两节点是否一个集合
  2. 思路 运用路径压缩+按质归并,全当复习基本操作

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

  1. 前序后要序求输出中序,如果不唯一把yes, 改变成No
  2. 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);
//}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值