PAT (Advanced Level) Practice 题解代码 - II (1051-1100)

PAT

PAT (Advanced Level) Practice - II(1051-1100)

--------------------------------------------------------------------------------

1001-1167(已更新至最新!)

1051-1100

链接:https://pan.baidu.com/s/1ZKiso4L947R3MZj7sxVtaw
提取码:sp2z
--------------------------------------------------------------------------------

更多详见>>

OJ题解系列 目录导航帖
--------------------------------------------------------------------------------

题目传送门

PAT (Advanced Level) Practice
--------------------------------------------------------------------------------

这里是PAT (Advanced Level) Practice - II(1051-1100)
这是一个全新的起点,我们完成了乙级考试的小目标,向着甲级考试的大目标前进,你将会看到一片新的世界,在数据结构和算法的大海里遨游
首先,我们讲讲两种考试的区别:
1.题面描述不同,乙级考试采用中文描述,甲级考试采用英文描述
2.题目数量不同,乙级考试是5道题,甲级考试是4道题
3.题目的分值不同,乙级考试的分值分布为15/20/20/20/25,甲级考试的分值分布为20/25/25/30
4.难度不同,甲级考试相对乙级考试来说会增加一个难度级别,主要体现在对数据结构的掌握上,如树和图——主要有BST/BBST/CBT/Heap/DAG,算法方面在原有的难度基础之上加深一点(比方说大模拟),引入了一些简单DP
知己知彼方能百战不殆,我们了解基本的区别之后,大家也不用太担心考试的难度问题,毕竟数据规模n不像竞赛要求那么高,很多算法用最普通的枚举方法往往也能取得满分!

接下来就是题解部分了,每道算法题都标注有对应的算法标签,对于那些易错、较难或是测试点比较特殊的题目会着重标注,本章推荐的题目有:

1053 Path of Equal Weight (30 分)
1079 Total Sales of Supply Chain (25 分)
1086 Tree Traversals Again (25 分)
1090 Highest Price in Supply Chain (25 分)
树,二叉树 + DFS
1056 Mice and Rice (25 分)大模拟
1057 Stack (30 分)分块/ST表
1067 Sort with Swap(0, i) (25 分)数论 + 模拟
1072 Gas Station (30 分)
1087 All Roads Lead to Rome (30 分)
图论 + Dijkstra

--------------------------------------------------------------------------------

1051 Pop Sequence (25 分)

算法标签: 模拟 + 栈
注意点: 本题模拟栈混洗的过程,并要求判断混洗后的结果是否为出栈序列,因此,对于每行输入,我们都需要开辟一个新的栈,不断压入元素,若该元素为出栈序列的首部,则弹出,检验下一个出栈首部,所有数据全部输入完成,且模拟过程结束后栈为空,表示为合法的出栈序列,否则就是不合法的序列

#include<bits/stdc++.h>
using namespace std;
int a[1005];
int M,N,K;
void check(){
	stack<int> s;
	bool f = true;
	int now = 1;
	for(int i=1;i<=N;i++){
		s.push(i);
		if(s.size()>M){
			f = false;
			break;
		}
		while(!s.empty() && s.top()==a[now]){
			s.pop();
			now++;
		}
	}
	if(!s.empty()){
		f = false;
	}
	if(f){
		printf("YES\n");
	}else{
		printf("NO\n");
	}
}

int main(){
	
	cin >> M >> N >> K;
	for(int t=1;t<=K;t++){
		for(int i=1;i<=N;i++){
			scanf("%d",&a[i]);
		}
		check();
	} 
	
	return 0; 
} 

1052 Linked List Sorting (25 分)

算法标签: 排序 + 链表

#include<bits/stdc++.h>
using namespace std;
struct node{
	int value;
	int next;
};
const int maxn = 1e5+5;
node n[maxn];
struct out{
	int add;
	int value;
};
out o[maxn];
bool cmp(out o1,out o2){
	return o1.value < o2.value;
}
int main(){
	int N;
	cin >> N;
	int start;
	cin >> start;
	int cnt = 0;
	for(int i=0;i<N;i++){
		int t;
		scanf("%d",&t); 
		scanf("%d%d",&n[t].value,&n[t].next);
	}
	while(start!=-1){
		o[cnt].add = start;
		o[cnt].value = n[start].value;
		cnt++;
		start = n[start].next;
	}
	sort(o,o+cnt,cmp);
	if(cnt==0){
		printf("0 -1\n");
	}else{
		printf("%d %05d\n",cnt,o[0].add);
	}
	
	for(int i=0;i<cnt;i++){
		if(i==cnt-1){
			printf("%05d %d -1\n",o[i].add,o[i].value);
		}else{
			printf("%05d %d %05d\n",o[i].add,o[i].value,o[i+1].add);
		}
	}
	return 0;
}

1053 Path of Equal Weight (30 分)

算法标签: 树,二叉树 + DFS
注意点: 一道好题!
这道题考察了树的DFS过程,从树根结点开始,遍历所有的元素结点,并统计PWL(带权路径长度):
1.若当前的PWL>S,则直接返回(剪枝)
2.若PWL==s,且当前访问的结点是叶结点,那么保存路径至vector中
所有路径记录完毕后,记得对所有路径进行排序,这个步骤很重要,因为不排序无法通过加强测试的数据点!

#include<bits/stdc++.h>
using namespace std;
int N,M,S;

struct node{
	int weight;
	vector<int> child;
};
node n[105];
int path[105];

bool cmp(int id1,int id2){
	return n[id1].weight > n[id2].weight;
}
vector<int> a[105];
int cnt = 0;

bool cmp2(vector<int> a,vector<int> b){
	return a>b;
}

void dfs(int depth,int index,int sum){
	if(sum>S){
		return;
	}else if(sum==S){
		if(n[index].child.size()==0){
			for(int i=0;i<depth;i++){
				a[cnt].push_back(path[i]);
			}
			cnt++;
			return;
		}else{
			return;
		}
	}else{
		for(int i=0;i<n[index].child.size();i++){
			int temp = n[index].child[i];
			path[depth] = n[temp].weight;
			dfs(depth+1,temp,sum+n[temp].weight);
		}
	}
	
	return;
}
int main() {
	cin >> N >> M >> S;
	for(int i=0;i<N;i++){
		cin >> n[i].weight;
	}
	for(int i=0;i<M;i++){
		int id;
		cin >> id;
		int k;
		cin >> k;
		for(int j=0;j<k;j++){
			int t;
			cin >> t;
			n[id].child.push_back(t);
		}
		sort(n[id].child.begin(),n[id].child.end(),cmp); 
	}
	path[0] = n[0].weight;
	dfs(1,0,n[0].weight);
	sort(a,a+cnt,cmp2);
	for(int i=0;i<cnt;i++){
		int l = a[i].size();
		for(int j=0;j<l;j++){
			if(j==0){
				printf("%d",a[i][j]);
			}else{
				printf(" %d",a[i][j]);
			}
		}
		printf("\n");
	}
	return 0;
}

1054 The Dominant Color (20 分)

算法标签: 数论
注意点: The Dominant Color实质是求像素点的众数!

#include<bits/stdc++.h>
using namespace std;
map<int,int> mp;
int main(){
	int M,N;
	cin >> M >> N;
	for(int i=0;i<N;i++){
		for(int j=0;j<M;j++){
			int t;
			cin >> t; 
			if(mp.find(t)!=mp.end()){
				mp[t]++;
			}else{
				mp[t] = 1;
			}
		}
	}
	int maxn = -1;
	int max_num = 0;
	for(auto it=mp.begin();it!=mp.end();it++){
		if(it->second>maxn){
			maxn = it->second;
			max_num = it->first;
		}
	}
	cout << max_num << endl;
	return 0;
} 

1055 The World’s Richest (25 分)

算法标签: 排序

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;

struct people{
	char name[10];
	int age;
	int worth;
};

people p[maxn];

bool cmp1(people p1,people p2){
	if(p1.worth!=p2.worth){
		return p1.worth > p2.worth;
	}else if(p1.age!=p2.age){
		return p1.age < p2.age;
	}else{
		return strcmp(p1.name,p2.name)<0;
	}
}
people p_valid[maxn];

int main(){
	cin.tie(0);
	cout.tie(0);
	int N,K;
	scanf("%d%d",&N,&K);
	
	for(int i=0;i<N;i++){
		scanf("%s%d%d",p[i].name,&p[i].age,&p[i].worth);
	}
	
	sort(p,p+N,cmp1);
	
	int cnt = 0;
	int t_age = p[0].age;
	int count = 0;
	for(int i=0;i<N;i++){
		if(t_age == p[i].age && count<100){
			strcpy(p_valid[cnt].name,p[i].name);
			p_valid[cnt].age = p[i].age;
			p_valid[cnt].worth = p[i].worth;
			count++;
			cnt++;
		}else{
			t_age = p[i].age;
			strcpy(p_valid[cnt].name,p[i].name);
			p_valid[cnt].age = p[i].age;
			p_valid[cnt].worth = p[i].worth;
			cnt ++;
			count = 1;
		}
	}
	for(int i=0;i<K;i++){
		int M,s_age,e_age;
		bool f = false;
		scanf("%d%d%d",&M,&s_age,&e_age);
		int count = 0;
		cout << "Case #" << i+1 << ":" << endl;
		for(int j=0;j<cnt;j++){
			if(p_valid[j].age >= s_age && p_valid[j].age <= e_age && count<M){
				printf("%s %d %d\n",p_valid[j].name,p_valid[j].age,p_valid[j].worth);
				f = true;
				count++;
			}
		}
		if(f){
			continue;
		}else{
			cout << "None" << endl;
		}
	}
	return 0;
} 

1056 Mice and Rice (25 分)

算法标签: 大模拟
注意点: 一道好题!
本题模拟分组比赛的过程,这里有个小技巧,可以边模拟边计算出老鼠们的排名,我们假设晋级下一轮的老鼠为x只,那么x等价于分组的数量group,因此,这一轮淘汰的老鼠分列第group+1名。
那么如何求group呢?其实很简单,本轮比赛老鼠的数量除以组内老鼠的数量 g r o u p = N N G group=\frac{N}{NG} group=NGN即可求得,下一轮老鼠的总数就是group(即group代替了N)

#include<bits/stdc++.h>
using namespace std;
int NP,NG;
int order[1005];

struct mouse{
	int rank;
	int weight;
};
mouse m[1005];

queue<int> q;

int main(){
	cin >> NP >> NG;
	for(int i=0;i<NP;i++){
		cin >> m[i].weight;
	}	
	for(int i=0;i<NP;i++){
		cin >> order[i];
	}
	for(int i=0;i<NP;i++){
		q.push(order[i]);
	}
	
	int temp = NP;
	int group;
	while(q.size()!=1){
		if(temp % NG==0){
			group = temp/NG;
		}else{
			group = temp/NG + 1;
		}
		
		for(int i=0;i<group;i++){
			int k = q.front();
			for(int j=0;j<NG;j++){
				if(i*NG+j>=temp){
					break;
				}
				int t = q.front();
				if(m[t].weight>m[k].weight){
					k = t;
				}
				m[t].rank = group+1;
				q.pop();
			}
			q.push(k);
		}
		temp = group;
	}
	int k = q.front();
	m[k].rank = 1;
	for(int i=0;i<NP;i++){
		if(i==NP-1){
			printf("%d",m[i].rank);
		}else{
			printf("%d ",m[i].rank);
		}
	}
	return 0;
} 

1057 Stack (30 分)

算法标签: 分块/ST表
注意点: 一道好题!
这道题如果按照普通枚举的方法肯定是TLE的,对于若干次查询,我们如何做到快速的找到中位数呢?
有2个方法,一个是中位数算法,另一个是分块法,这里不讲中位数算法,有兴趣可查阅相关的资料,接下来主要讲讲分块算法
分块,就是把一个哈希表分成若干块,以块为单位的形式查找,那么这里我们将整个区间分成 O ( n ) O(\sqrt n) O(n )块,每块中含有 O ( n ) O(\sqrt n) O(n )个元素,每次查询先查询块,然后再查询块内的元素,因此可在 O ( n ) O(\sqrt n) O(n )的时间内找到中位数并输出,能够满足题目的查询速度要求

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
const int sq = (int)sqrt(maxn);
int N;
int block[350];
int a[maxn];
stack<int> st;
int main(){
	scanf("%d",&N);
	for(int i=0;i<N;i++){
		string s;
		cin >> s;
		if(s=="Pop"){
			if(st.empty()){
				printf("Invalid\n");
			}else{
				int t = st.top();
				printf("%d\n",t);
				st.pop();
				a[t]--;
				block[t/sq]--;
			}
		}else if(s=="PeekMedian"){
			if(st.empty()){
				printf("Invalid\n");
			}else{
				int t = st.size();
				int K; 
				if(t%2){
					K = (t+1)/2;
				}else{
					K = t/2;
				}
				int cnt1 = 0;
				int sum = 0;
				while(sum+block[cnt1]<K){
					sum += block[cnt1];
					cnt1++;
				}
				
				int cnt2 = sq*cnt1;
				while(sum<K){
					sum += a[cnt2];
					cnt2++;
				}
				printf("%d\n",cnt2-1);	
			}
		}else if(s=="Push"){
			int t;
			scanf("%d",&t);
			st.push(t);
			block[t/sq]++;
			a[t]++;
		}
	}
	return 0;
} 

1058 A+B in Hogwarts (20 分)

算法标签: 模拟 + 字符串

#include<bits/stdc++.h>
using namespace std;
string str1,str2;
int a[3];
int b[3];
int c[3];

int main(){
	cin >> str1 >> str2;
	int site1 = str1.find('.');
	int site2 = str1.find('.',site1+1);
	for(int i=0;i<site1;i++){
		a[0] = a[0]*10 + str1[i] - '0'; 
	} 
	for(int i=site1+1;i<site2;i++){
		a[1] = a[1]*10 + str1[i] - '0';
	}
	for(int i=site2+1;i<str1.size();i++){
		a[2] = a[2]*10 + str1[i] - '0';
	} 
	
	site1 = str2.find('.');
	site2 = str2.find('.',site1+1);
	for(int i=0;i<site1;i++){
		b[0] = b[0]*10 + str2[i] - '0'; 
	} 
	for(int i=site1+1;i<site2;i++){
		b[1] = b[1]*10 + str2[i] - '0';
	}
	for(int i=site2+1;i<str2.size();i++){
		b[2] = b[2]*10 + str2[i] - '0';
	} 
	
	int jw = 0;
	for(int i=2;i>=0;i--){
		a[i] = a[i] + b[i];
		if(i==2){ 
			a[i] = a[i] + jw; 
			jw = a[i]/29;
			a[i] = a[i] % 29;
		}else if(i==1){
			a[i] = a[i] + jw;
			jw = a[i]/17;
			a[i] = a[i] % 17;
		}else{
			a[i] += jw;
		}
	}
	cout << a[0] << "." << a[1] << "." << a[2] << endl; 
	return 0;
} 

1059 Prime Factors (25 分)

算法标签: 数论 + 素数筛

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
bool a[maxn] = {1,1,0};
int b[maxn];
int cnt = 0;
void init(){
	for(int i=2;i<maxn;i++){
		if(!a[i]){
			for(int j=2*i;j<maxn;j+=i){
				a[j] =1;
			}
		}
	}
	for(int i=2;i<maxn;i++){
		if(!a[i]){
			b[cnt++] = i;
		}
	}
}

struct factor{
	int p;
	int e = 0;
};
factor f[maxn];
int index_t = 0;
int main(){
	init();
	int N;
	scanf("%d",&N);
	if(N==1){
		printf("1=1");
		return 0;
	}
	int out = N;
	for(int i=0;i<cnt;i++){
		if(N%b[i]==0){
			f[index_t].p = b[i];
			while(N%b[i]==0 && N!=1){
				N/=b[i];
				f[index_t].e++;
			}
			index_t++;
		}
		if(N==1){
			break;
		}
	}
	if(N>1){
		f[index_t].p = N;
		f[index_t].e++;
		index_t++;
	}
	printf("%d=",out);
	for(int i=0;i<index_t;i++){
		if(i==0){
			if(f[i].e == 1){
				printf("%d",f[i].p);
			}else{
				printf("%d^%d",f[i].p,f[i].e);
			}
		}else{
			printf("*");
			if(f[i].e == 1){
				printf("%d",f[i].p);
			}else{
				printf("%d^%d",f[i].p,f[i].e);
			}
		}
	}
	return 0;
} 

1060 Are They Equal (25 分)

算法标签: 模拟 + 字符串

#include<bits/stdc++.h>
using namespace std;

int main(){
	int N;
	scanf("%d",&N);
	string s1,s2;
	cin >> s1 >> s2;
	while(1){
		if(s1[0]=='0'){
			s1.erase(s1.begin());
		}else{
			break;
		}
	}
	while(1){
		if(s2[0]=='0'){
			s2.erase(s2.begin());
		}else{
			break;
		}
	}
	int len1 = s1.size();
	int len2 = s2.size();
	int E1 = 0;
	int E2 = 0;
	string r1 ="";
	string r2 ="";
	
	
	if(s1[0]=='.'){
		for(int i=1;i<len1;i++){
			if(s1[i]=='0'){
				E1--;
			}else{
				break;
			}
		}	
		int t = N;
		int now = 1 + abs(E1);
		while(t--){
			if(now<len1){
				r1 += s1[now];
				now++;
			}else{
				r1 += "0";
			}
		}
	}else{
		for(int i=0;i<len1;i++){
			if(s1[i]=='.'){
				break;
			}else{
				E1++;
			}
		}
		int now = 0;
		int t=N;
		while(t){
			if(now<len1){
				if(s1[now]!='.'){
					r1 += s1[now];
					t--;
				}
				now++;
			}else{
				r1 += "0";
				t--;
			}
		}
	}
	
	
	if(s2[0]=='.'){
		for(int i=1;i<len2;i++){
			if(s2[i]=='0'){
				E2--;
			}else{
				break;
			}
		}	
		int t = N;
		int now = 1 + abs(E2);
		while(t--){
			if(now<len2){
				r2 += s2[now];
				now++;
			}else{
				r2 += "0";
			}
		}
	}else{
		for(int i=0;i<len2;i++){
			if(s2[i]=='.'){
				break;
			}else{
				E2++;
			}
		}
		int t = N;
		int now = 0;
		while(t){
			if(now<len2){
				if(s2[now]!='.'){
					r2 += s2[now];
					t--;
				}
				now++;
			}else{
				r2 += "0";
				t--;
			}
		}
	}
	
	if(E1==E2 && r1==r2){
		printf("YES 0.%s*10^%d\n",r1.c_str(),E1);
	}else if(r1==r2 && r1[0]=='0' && r2[0]=='0'){
		printf("YES 0.%s*10^%d\n",r1.c_str(),0);
	}else{
		printf("NO 0.%s*10^%d 0.%s*10^%d\n",r1.c_str(),E1,r2.c_str(),E2);
	}
	return 0;
}

1061 Dating (20 分)

算法标签: 模拟 + 字符串

#include<bits/stdc++.h>
using namespace std;
string str[7] = {"MON","TUE","WED","THU","FRI","SAT","SUN"};
int isupper(char c){
	if(c>='A' && c<='G'){
		return 1;
	}else{
		return 0;
	}
}

int isalpha(char c){
	if(c>='A' && c<='Z'){
		return 1;
	}else if(c>='a' && c<='z'){
		return 1;
	}else{
		return 0;
	}
}

int main(){
	string s1,s2,s3,s4;
	char day,hour;
	int minute;
	cin >> s1 >> s2 >> s3 >> s4;
	int size1 = min(s1.size(),s2.size());
	int size2 = min(s3.size(),s4.size());
	int count = 0;
	for(int i=0;i<size1;i++){
		if(s1[i]==s2[i] && count == 0 && isupper(s1[i]) && isupper(s2[i])){
			day = s1[i];
			count++;
		}else if(s1[i]==s2[i] && ((s1[i]>='0' && s1[i]<='9')||(s2[i]>='A' && s2[i]<='N')) && count!=0){
			hour = s1[i];
			break;
		}
	}	
	for(int i=0;i<size2;i++){
		if(s3[i]==s4[i] && isalpha(s3[i]) && isalpha(s4[i])){
			minute = i; 
			break;
		} 
	}
	string daystr = str[(int)(day-'A')];
	int h;
	
	if(isalpha(hour)){
		h = hour - 'A' + 10;
	}else{
		h = hour -'0';
	}
	
	cout << daystr << " ";
	if(h<10){
		cout << "0" << h;
	}else{
		cout << h ;
	}
	cout << ":";
	if(minute<10){
		cout << "0" << minute;
	}else{
		cout << minute;
	}
	cout << endl;
	return 0;
}

1062 Talent and Virtue (25 分)

算法标签: 排序

#include<bits/stdc++.h>
using namespace std;
int N,L,H;
typedef struct score{
	int IDnum;
	int Dscore;
	int Cscore;
}score;
const int maxn = 1e5+5;
score DC1[maxn];
score DC2[maxn];
score DC3[maxn];
score DC4[maxn];
bool cmp(score s1,score s2){
	if(s1.Cscore+s1.Dscore>s2.Cscore+s2.Dscore){
		return true;
	}else if(s1.Cscore+s1.Dscore == s2.Cscore+s2.Dscore){
		if(s1.Dscore>s2.Dscore){
			return true;
		}else if (s1.Dscore == s2.Dscore){
			if(s1.IDnum<s2.IDnum){
				return true;
			}else{
				return false;
			}
		}else{
			return false;
		}
	}else{
		return false;
	}
}

int main(){
	cin >> N >> L >> H;
	int first = 0,second =0,third =0,fourth =0;
	int nopass = 0;
	for(int i=0;i<N;i++){
		int a,b,c;
		scanf("%d%d%d",&a,&b,&c);
		if(b<L || c<L){
			nopass++;
			continue;
		}else if(b>=H && c>=H){
			DC1[first].IDnum = a;
			DC1[first].Dscore = b;
			DC1[first++].Cscore = c;
		}else if(b>=H && c<H){
			DC2[second].IDnum = a;
			DC2[second].Dscore = b;
			DC2[second++].Cscore = c;
		}else if(b<H && c<H && b>=c){
			DC3[third].IDnum = a;
			DC3[third].Dscore = b;
			DC3[third++].Cscore = c;
		}else{
			DC4[fourth].IDnum = a;
			DC4[fourth].Dscore = b;
			DC4[fourth++].Cscore = c;
		}
	}
	cout << N-nopass << endl;
	
	sort(DC1,DC1+first,cmp);
	sort(DC2,DC2+second,cmp);
	sort(DC3,DC3+third,cmp);
	sort(DC4,DC4+fourth,cmp);
	
	for(int i=0;i<first;i++){
		printf("%d %d %d\n",DC1[i].IDnum,DC1[i].Dscore,DC1[i].Cscore);
	}
	for(int i=0;i<second;i++){
		printf("%d %d %d\n",DC2[i].IDnum,DC2[i].Dscore,DC2[i].Cscore);
	}
	for(int i=0;i<third;i++){
		printf("%d %d %d\n",DC3[i].IDnum,DC3[i].Dscore,DC3[i].Cscore);
	}
	for(int i=0;i<fourth;i++){
		printf("%d %d %d\n",DC4[i].IDnum,DC4[i].Dscore,DC4[i].Cscore);
	}
	return 0;
}

1063 Set Similarity (25 分)

算法标签: 集合
注意点: 本题考察的重点是集合,由于集合中的元素不能重复,因此,可用STL的set进行操作,每次查询输入两个集合的编号,我们采用枚举法判断集合的相似度,最后保留1位小数后输出

#include<bits/stdc++.h>
using namespace std;
set<int> a[55];
double query[60][60];
int main(){
    int N;
    scanf("%d",&N);
    for(int i=1;i<=N;i++){
        int M;
        scanf("%d",&M);
        for(int j=0;j<M;j++){
            int t;
            scanf("%d",&t);
            a[i].insert(t);
        }
    }
     
    int K;
    scanf("%d",&K);
    for(int i=0;i<K;i++){
        int g,h;
        scanf("%d%d",&g,&h);
        set<int>::iterator it1;
        set<int>::iterator it2;
        int Nc = 0;
        for(it1 = a[g].begin(),it2 = a[h].begin();it1!=a[g].end() && it2!=a[h].end();){
            if(*it1 == *it2){
                Nc++;
                it1++;
                it2++;
            }else if(*it1<*it2){
                it1++;
            }else{
                it2++;
            }
        }
        int Nn = a[g].size() + a[h].size() - Nc;
        double r = (Nc * 1.0) /(Nn * 1.0);
        printf("%.1lf%%\n",r*100.0);
    }
    return 0;
} 

1064 Complete Binary Search Tree (30 分)

算法标签: 树,二叉树 + CBT + BST
注意点: 本题不必模拟树中结点的插入过程,首先输入数据后,对数据进行排序,由于BST的中序遍历必定是有序的,因此中序遍历的结果就是排序后的数组,那么层序遍历的求解就可以转化为根结点的中序遍历过程,root位置代表了当前结点的层次序号,而第k个被遍历的元素就是排序后数组的第k项

#include<bits/stdc++.h>
using namespace std;
int a[1005];
int b[1005];
int cnt = 1;
int N;

void InOrder(int root){
	if(root>N){
		return;
	}
	InOrder(2*root);
	b[root] = a[cnt++];
	InOrder(2*root+1);
}

int main(){
	cin >> N;
	for(int i=1;i<=N;i++){
		cin >> a[i];
	}
	sort(a+1,a+N+1); 
	InOrder(1);
	for(int i=1;i<=N;i++){
		if(i==1){
			printf("%d",b[i]);
		}else{
			printf(" %d",b[i]);
		}
	}
	printf("\n");
	
	return 0;
} 

1065 A+B and C (64bit) (20 分)

算法标签: 数论
注意点: 需要特判上溢和下溢的情况
上溢是指两个正数相加,结果却为负数
下溢是指两个负数相加,结果却为正数

#include<bits/stdc++.h>
using namespace std;

int main(){
	int T;
	cin >> T;
	long long a,b,c;
	for(int i=1;i<=T;i++){
		scanf("%lld%lld%lld",&a,&b,&c);
		cout << "Case #" << i << ": ";
		long long res = a+b;
		if(a>0 && b>0 && res<0){
			cout << "true" << endl;
		}else if(a>0 && b>0 && res==0){
			cout << "true" << endl;
		}else if(a<0 && b<0 && res>0){
			cout << "false" << endl;
		}else if(a<0 && b<0 && res==0){
			cout << "false" << endl;
		}else if(res>c){
			cout << "true" << endl;
		}else{
			cout << "false" << endl;
		}
	}
	
	
	return 0;
} 

1066 Root of AVL Tree (25 分)

算法标签: 树,二叉树 + 平衡树
注意点: 平衡树模板题,先建树,然后输出根结点的值

#include<bits/stdc++.h>
using namespace std;
int a[25];
struct node{
	int data;
	int height;
	node* lchild;
	node* rchild;
};
node* root = NULL;
node* newnode(int v){
	node* Node = new node;
	Node->data = v;
	Node->height = 1;
	Node->lchild = NULL;
	Node->rchild = NULL;
	return Node; 
}
int getheight(node *root){
	if(root==NULL){
		return 0;
	}
	return root->height;
}
void updateheight(node *root){
	root->height = max(getheight(root->lchild),getheight(root->rchild))+1;
}
int bf(node* root){
	return getheight(root->lchild) - getheight(root->rchild);
}
void R(node* &root){
	node* temp = root->lchild;
	root->lchild = temp->rchild;
	temp->rchild = root;
	updateheight(root);
	updateheight(temp);
	root = temp;
}
void L(node* &root){
	node* temp = root->rchild;
	root->rchild = temp->lchild;
	temp->lchild = root;
	updateheight(root);
	updateheight(temp);
	root = temp;
}

void insert(node* &root,int x){
	if(root==NULL){
		root = newnode(x);
		return;
	}
	if(x<root->data){
		insert(root->lchild,x);
		updateheight(root);
		if(bf(root)==2){
			if(bf(root->lchild)==1){
				R(root);
			}else{
				L(root->lchild);
				R(root);
			}
		}
	}else{
		insert(root->rchild,x);
		updateheight(root);
		if(bf(root)==-2){
			if(bf(root->rchild)==-1){
				L(root);
			}else{
				R(root->rchild);
				L(root);
			}
		}
	}
}
int main(){
	int N;
	cin >> N;
	for(int i=0;i<N;i++){
		cin >> a[i];
	}
	for(int i=0;i<N;i++){
		insert(root,a[i]);
	}
	cout << root->data << endl;
	return 0;
} 

1067 Sort with Swap(0, i) (25 分)

算法标签: 数论 + 模拟
注意点: 一道好题!这道题考察了如何求解交换的最小次序,首先我们观察任意一个数列,这个数列有序当且仅当元素都在对应的位置上,即 a [ i ] = i a[i]=i a[i]=i,若要执行Swap变换,那么就必须和0进行交换,而0这个元素有序当且仅当最后一个元素有序后,0自动有序。那么该问题求解的过程就转化为除了0之外的所有元素有序时最小次数。此时问题分成2个部分:若0不在a[0]上,可交换a[a[0]]与a[0]的值,那么a[0]就位于对应位置上了;若0在a[0]上,此时我们选择从前向后未有序的第一个元素,和0交换,然后再反复执行上述操作,直到全部有序为止,输出交换的次数即为答案。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
int a[maxn];

int main(){
	int N;
	scanf("%d",&N);
	int cnt = 0;
	int swapcount = 0;
	for(int i=0;i<N;i++){
		scanf("%d",&a[i]);
		if(a[i]!=0 && i!=a[i]){
			cnt++;
		}
	}
	int k = 1;
	while(cnt>0){
		if(a[0] == 0){
			for(int i=k;i<N;i++){
				if(i!=a[i]){
					k = i;
					break;
				}
			}
			swap(a[0],a[k]);
			swapcount++;
		}
		while(a[0]!=0){
			swap(a[a[0]],a[0]);
			swapcount++;
			cnt--;
		}	
		
	}
	printf("%d\n",swapcount);
	return 0;
} 

1068 Find More Coins (30 分)

算法标签: DP + DFS
注意点: 要找出一些数字和为M,这是一道经典的0-1背包问题,建立状态转移方程:
d p [ j ] = m a x ( d p [ j ] , d p [ j − a [ i ] ] + a [ i ] ) dp[j] = max(dp[j],dp[j-a[i]]+a[i]) dp[j]=max(dp[j],dp[ja[i]]+a[i])
由于题目中要输出字典序最小的,因此需要对数据元素倒排,然后进行DP操作,DP过程中记录路径结点,choice[i][j]表示选了第i个数后和为j,最后再逆序DFS求出每个选入的元素,依次输出即可

#include<bits/stdc++.h>
using namespace std;
int N,M;
int a[10005];
int dp[105];
bool choice[10005][105];
int ans[105];
int cnt = 0;

int main(){
	scanf("%d%d",&N,&M);
	for(int i=1;i<=N;i++){
		scanf("%d",&a[i]); 
	}
	sort(a+1,a+N+1);
	reverse(a+1,a+N+1);
	for(int i=1;i<=N;i++){
		for(int j=M;j>=a[i];j--){
			if(dp[j-a[i]]+a[i]>=dp[j]){
				dp[j] = max(dp[j],dp[j-a[i]]+a[i]);
				choice[i][j] = true;
			}
		}
	}
	
	if(dp[M]!=M){
		printf("No Solution\n");
	}else{
		int j = M;
		int i = N;
		while(j){
			if(choice[i][j]){
				ans[cnt++] = a[i];
				j -= a[i]; 
			}
			i--;
		}
		for(int i=0;i<cnt;i++){
			if(i==0){
				printf("%d",ans[i]);
			}else{
				printf(" %d",ans[i]);
			}
		}
		printf("\n");
	}
	return 0;
} 

1069 The Black Hole of Numbers (20 分)

算法标签: 数论 + 模拟

#include<bits/stdc++.h>
using namespace std;
int N;
int a[4];
int b[4];
int c[4];
bool cmp(int a,int b){
	return a>b;
}
int main(){
	cin >> N;
	a[0] = N / 1000;
	a[1] = (N / 100) % 10;
	a[2] = (N / 10) % 10;
	a[3] = N % 10;
	if((a[0]==a[1])&&(a[1]==a[2])&&(a[2]==a[3])){
		cout << a[0] << a[1] << a[2] << a[3] << " - " << a[0] << a[1] << a[2] << a[3] << " = 0000" << endl;
		return 0;
	}else{
		while(1){
			sort(a,a+4,cmp);
			cout << a[0] << a[1] << a[2] << a[3] << " - " ;
			for(int i=0;i<4;i++){
				b[i] = a[i];
			}
			sort(b,b+4);
			cout << b[0] << b[1] << b[2] << b[3] << " = ";
			for(int i=3;i>=0;i--){
				if(a[i]-b[i]<0){
					c[i] = a[i] + 10 - b[i];
					a[i-1]--;
				}else{
					c[i] = a[i] - b[i];
				}
			}	
			cout << c[0] << c[1] << c[2] << c[3] << endl;
			if(c[0]==6 && c[1]==1 && c[2]==7 && c[3]==4){	
				break;
			}else{
				for(int i=0;i<4;i++){
					a[i] = c[i];
				}
			}
		}
		
	}
	
	return 0;
}

1070 Mooncake (25 分)

算法标签: 模拟 + 排序

#include<bits/stdc++.h>
using namespace std;
int N,D;
int maxn = 1005;
typedef struct mooncake{
	double num;
	double price;
	double singleprice;
}mooncake;
bool cmp(mooncake m1,mooncake m2){
	return m1.singleprice > m2.singleprice;
}
int main(){
	cin >> N >> D;
	mooncake m[N];
	for(int i=0;i<N;i++){
		cin >> m[i].num;
	}
	for(int i=0;i<N;i++){
		cin >> m[i].price;
	}
	for(int i=0;i<N;i++){
		m[i].singleprice = (m[i].price * 1.0) /(m[i].num * 1.0);
	}
	
	sort(m,m+N,cmp);
	
	int site = 0;
	double totalprice = 0.0;
	
	while(D!=0){
		if(m[site].num <= D){
			D -= m[site].num;
			totalprice = totalprice + m[site].price;
		}else{
			totalprice = totalprice + m[site].singleprice * D;
			D = 0;
		}
		site++;
	}
	printf("%.2lf\n",totalprice);
	
	return 0;
}

1071 Speech Patterns (25 分)

算法标签: 模拟 + 字符串

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1048576 + 5;
char s[maxn];
map<string,int> mp; 
int iscase(char ch){
    if((ch>='A' && ch<='Z') || (ch>='a' && ch<='z')){
        return 1;
    }else{
        return 0;
    }
}
int check(char ch){
    if(iscase(ch) || (ch>='0' && ch<='9')){
        return 1;
    }else{
        return 0;
    }
}
  
int main(){
	string tmp;
	getline(cin,tmp);
	strcpy(s,tmp.c_str());
    int len = strlen(s);
    string t = "";
 
    for(int i=0;i<len;i++){
        if(check(s[i])){
            if(iscase(s[i])){
                t += tolower(s[i]); 
            }else{
                t += s[i];
            }
        }
        if(!check(s[i]) || i==len-1){
            if(t.length()!=0){
                mp[t]++;
            }
            t.clear();
        }
    }
      
    map<string,int>::iterator it = mp.begin();
    string ans;
    int res = -1;
    for(;it!=mp.end();it++){
        if(it->second>res){
            res = it->second;
            ans = it->first;
        }
    }
    cout << ans << " " << res << endl;
    return 0;
}

1072 Gas Station (30 分)

算法标签: 图论 + Dijkstra
注意点: 参考P1003/P1018/P030,解法相同

#include<bits/stdc++.h>
using namespace std;
int N,M,K,D;

double ans = -1;
double average = 1e8;
int res = -1;

struct node{
	int v;
	int dis;
};

vector<node> G[1050];
int dp[1050];
bool vis[1050];

void dijstra(int s){
	memset(vis,0,sizeof(vis));
	fill(dp+1,dp+N+M+1,INT_MAX);
	dp[s] = 0;
	for(int i=1;i<=N+M;i++){
		int u = -1;
		int minnum = INT_MAX;
		for(int j=1;j<=N+M;j++){
			if(!vis[j] && dp[j]<minnum){
				minnum = dp[j];
				u = j;
			}
		}
		if(u==-1){
			return;
		}
		vis[u] = true;
		for(int j=0;j<G[u].size();j++){
			int v = G[u][j].v;
			int dis = G[u][j].dis;
			if(!vis[v]){
				if(dp[u]+dis<dp[v]){
					dp[v] = dp[u]+dis; 
				}
			}
		}
	}
}

void deal(int M){
	bool f = true;
	int mindis = INT_MAX;
	
	for(int i=1;i<=N;i++){
		if(dp[i]<mindis){
			mindis = dp[i];
		}
		if(dp[i]>D){
			f = false;
			break;
		}
	}
	
	if(f){
		double tmp = 0.0;
		for(int i=1;i<=N;i++){
			tmp += 1.0*dp[i]/N;
		}
		
		if(mindis>ans){
			ans = mindis;
			average = tmp;
			res = M;
		}else if(mindis==ans){
			if(tmp<average){
				average = tmp;
				res = M;	
			}	
		}
	}
}

int main(){
	scanf("%d%d%d%d",&N,&M,&K,&D);
	for(int i=0;i<K;i++){
		int p1 = 0;
		int p2 = 0;
		int dist;
		
		string t1;
		string t2;
		cin >> t1 >> t2;
		scanf("%d",&dist);
		if(t1[0] == 'G'){
			for(int j=1;j<t1.size();j++){
				p1 = p1*10 + t1[j]-'0';
			}
			p1 = p1 + N;
		}else{
			for(int j=0;j<t1.size();j++){
				p1 = p1*10 + t1[j]-'0';
			}
		}
		if(t2[0] == 'G'){
			for(int j=1;j<t2.size();j++){
				p2 = p2*10 + t2[j]-'0';
			}
			p2 = p2 + N;
		}else{
			for(int j=0;j<t2.size();j++){
				p2 = p2*10 + t2[j]-'0';
			}
		}
		
		node temp;
		temp.dis = dist;
		temp.v = p2;
		G[p1].push_back(temp);
		temp.v = p1;
		G[p2].push_back(temp);
	}
	
	for(int i=N+1;i<=N+M;i++){
		dijstra(i);
		deal(i);
	}
	if(res == -1){
		printf("No Solution\n");
	}else{
		printf("G%d\n",res-N);
		printf("%.1lf %.1lf\n",ans,average);
	}
	
	
	return 0;
} 

1073 Scientific Notation (20 分)

算法标签: 模拟 + 字符串

#include<bits/stdc++.h>
using namespace std;

int main(){
	string str;
	cin >> str;
	int site = str.find('E');
	string n = str.substr(1,site-1);
	string e = str.substr(site+1);
	int en = stoi(e);
	if(str[0] == '-'){
		 cout << "-";
	}
	if(en>=0){
		cout << str[1];
		int j=2,cnt=0;
		for(j=2;j<site && cnt<en;j++){
			if(str[j]=='.'){
				continue;
			}else{
				cout << str[j];
				cnt++;
			}
		} 
		if(j==site){
			for(int i=0;i<en-cnt;i++){
				cout << "0" ; 
			}
		}else{
			cout <<".";
			for(int i=j;j<site;j++){
				cout << str[j];
			}
		}
	}else{
		cout << "0.";
		for(int i=0;i<abs(en)-1;i++){
			cout << "0";
		}
		cout << str[1];
		for(int j=2;j<site;j++){
			if(str[j]=='.'){
				continue;
			}else{
				cout << str[j];
			}
		}
	}
	return 0;
} 

1074 Reversing Linked List (25 分)

算法标签: 模拟 + 链表

#include<bits/stdc++.h>
using namespace std;
int start,N,K;
const int maxn = 1e5+5;
int e_data[maxn];
int eadd[maxn];
int listnum[maxn];

int main(){
	cin.tie(0);
	cout.tie(0);
	cin >> start >> N >> K;
	for(int i=0;i<N;i++){
		int addr;
		cin >> addr;
		cin >> e_data[addr] >> eadd[addr];
	}
	int nextadd = start;
	int count = 0;
	while(nextadd!=-1){
		listnum[count++] = nextadd;
		nextadd = eadd[nextadd];
	}
	for(int i=0;i<(count-count%K);i+=K){
		reverse(listnum+i,listnum+i+K);
	}
	for(int i=0;i<count;i++){
		if(i!=count-1){
			printf("%05d %d %05d\n",listnum[i],e_data[listnum[i]],listnum[i+1]);
		}else{
			printf("%05d %d %d\n",listnum[i],e_data[listnum[i]],-1);
		}
	}
	return 0;
}

1075 PAT Judge (25 分)

算法标签: 模拟 + 排序

#include<bits/stdc++.h>
using namespace std;
int score[10];

const int maxn = 1e5+5;

struct student{
	int total_score=0;
	int score_get[6] = {-1,-1,-1,-1,-1,-1};
	int rank;
	int perfect = 0;
	int id;
};

student stu[maxn];

bool cmp(student s1,student s2){
	if(s1.score_get[0]!=s2.score_get[0]){
		return s1.score_get[0] > s2.score_get[0];
	}else if(s1.total_score!=s2.total_score){
		return s1.total_score > s2.total_score;
	}else if(s1.perfect!=s2.perfect){
		return s1.perfect > s2.perfect;
	}else{
		return s1.id < s2.id;
	}
}

int main(){
	int N,M,K;
	scanf("%d%d%d",&N,&K,&M);
	for(int i=1;i<=K;i++){
		scanf("%d",&score[i]);
	}
	
	for(int i=0;i<M;i++){
		int id,pro_id,score_num;
		scanf("%d%d%d",&id,&pro_id,&score_num);
		stu[id].id = id;
		if(score_num==-1){
			if(stu[id].score_get[pro_id] == -1){
				stu[id].score_get[pro_id] = -2;
			}
		}else{
			stu[id].score_get[0] = 1;
			if(stu[id].score_get[pro_id]<score_num){
				stu[id].score_get[pro_id] = max(stu[id].score_get[pro_id],score_num);
			}
			int t = 0;
			int count = 0;
			for(int j=1;j<=K;j++){
				if(stu[id].score_get[j]!=-1 && stu[id].score_get[j]!=-2){
					count += stu[id].score_get[j];
				}
				if(stu[id].score_get[j] == score[j]){
					t++;
				}
			}
			stu[id].perfect = t;
			stu[id].total_score = count;
		}
	}
	sort(stu,stu+maxn,cmp);
	
	stu[0].rank = 1;
	for(int i=0;i<maxn;i++){
		if(stu[i].score_get[0] == -1){
			break;
		}else{
			if(stu[i].total_score == stu[i+1].total_score){
				stu[i+1].rank = stu[i].rank;
			}else{
				stu[i+1].rank = i+2;
			}
			printf("%d %05d %d",stu[i].rank,stu[i].id,stu[i].total_score);
			for(int j=1;j<=K;j++){
				if(stu[i].score_get[j]==-1){
					printf(" -");
				}else if(stu[i].score_get[j] == -2){
					printf(" 0");
				}else{
					printf(" %d",stu[i].score_get[j]);
				}
			}
			printf("\n");
		}
	}
	
	
	return 0;
}

1076 Forwards on Weibo (30 分)

算法标签: 图论 + BFS
注意点: 从查询的源点出发,BFS遍历不超过L层,统计L层的信息即可

#include<bits/stdc++.h>
using namespace std;
int a[1005][1005];
bool f[1005];
struct node{
	int layer;
	int number;
};
int N,L;

int BFS(int u){
	node s;
	f[u] = true;
	s.layer = 0;
	s.number = u;
	queue<node> q;
	q.push(s);
	int total = -1;
	while(!q.empty()){
		node front = q.front();
		q.pop();
		if(front.layer>L){
			break;
		}else{
			total++;
		}
		for(int i=1;i<=N;i++){
			if(!f[i] && a[front.number][i]){
				f[i] = true;
				node tmp;
				tmp.layer = front.layer+1;
				tmp.number = i;
				q.push(tmp);
			}
		}
	}
	return total;
}
int main(){
	cin >> N >> L;
	for(int i=1;i<=N;i++){
		int k;
		scanf("%d",&k);
		for(int j=0;j<k;j++){
			int v;
			scanf("%d",&v);
			a[v][i] = 1;
		}
	}
	int k;
	scanf("%d",&k);
	for(int i=0;i<k;i++){
		int u;
		scanf("%d",&u);
		memset(f,0,sizeof(f));
		printf("%d\n",BFS(u));
	}
	
	return 0; 
}

1077 Kuchiguse (20 分)

算法标签: 模拟 + 字符串
注意点: 从每个字符串的末尾开始逆序枚举,求解最长的公共后缀

#include<bits/stdc++.h>
using namespace std;
string s[105];
int main(){
	int N;
	cin >> N;
	getchar();
	int minn = INT_MAX;
	for(int i=0;i<N;i++){
		getline(cin,s[i]);
		int len = s[i].size();
		reverse(s[i].begin(),s[i].end());
		minn = min(minn,len);
	}
	int cnt = 0;
	for(int i=0;i<minn;i++){
		bool f = true;
		char c = s[0][i];
		for(int j=0;j<N;j++){
			if(c == s[j][i]){
				continue;
			}else{
				f = false;
				break;
			}
		}
		if(f){
			cnt++;
		}else{
			break;
		}
	}
	if(cnt){
		for(int i=cnt-1;i>=0;i--){
			cout << s[0][i];
		} 
		cout << endl;
	}else{
		cout << "nai" << endl; 
	}
	return 0;
}

1078 Hashing (25 分)

算法标签: 模拟 + 哈希
注意点: 模拟哈希表的工作过程,哈希函数本题采用的是除留取余法,解决冲突采用的是平方试探法

#include<bits/stdc++.h>
using namespace std;

const int maxn = 1e5+5;
bool p[maxn]={1,1,0};
int a[maxn];
bool hashT[maxn];

void init(){
	for(int i=2;i<maxn;i++){
		if(!p[i]){
			for(int j=2*i;j<maxn;j+=i){
				p[j] = 1;
			}
		}
	}
}

int main(){
	init();
	int msize;
	int N;
	int Tsize;
	scanf("%d%d",&msize,&N);
	
	for(int i=0;i<N;i++){
		scanf("%d",&a[i]);
	}
	
	if(!p[msize]){
		Tsize = msize;
	}else{
		for(int i=msize+1;;i++){
			if(!p[i]){
				Tsize = i;
				break;
			}
		}
	}
	for(int i=0;i<N;i++){
		int key = a[i] % Tsize;
		if(!hashT[key]){
			hashT[key] = true;
			if(i==0){
				printf("%d",key);
			}else{
				printf(" %d",key);
			}
		}else{
			bool f = false;
			for(int step=1;step<Tsize;step++){
				int k = (a[i]+step*step)%Tsize;
				if(!hashT[k]){
					hashT[k] = true;
					if(i==0){
						printf("%d",k);
					}else{
						printf(" %d",k);
					}
					f = true;
					break;
				}
			} 
			if(!f){
				if(i==0){
					printf("-");
				}else{
					printf(" -");
				}
			}
		}
	}
	
	return 0;
} 

1079 Total Sales of Supply Chain (25 分)

算法标签: 树,二叉树 + DFS
注意点: 参考P1021/P1053,解法相同

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
vector<int> child[maxn];
int a[maxn];
int N;
double P;
double r;
bool hashT[maxn];
int mindepth = INT_MAX;
int minnum = 0;
double res = 0.0;

void dfs(int depth,int root){
	if(child[root].size()==0){
		res += P*pow(1.0+r/100.0,depth)*a[root];
		return;
	}
	for(int i=0;i<child[root].size();i++){
		dfs(depth+1,child[root][i]);
	}
}

int main(){
	cin >> N >> P >> r;
	for(int i=0;i<N;i++){
		int k;
		scanf("%d",&k);
		if(k==0){
			scanf("%d",&a[i]);
		}else{
			for(int j=0;j<k;j++){
				int t;
				scanf("%d",&t);
				child[i].push_back(t);
				hashT[t] = 1;
			}
		}
	}
	int root;
	for(int i=0;i<N;i++){
		if(!hashT[i]){
			root = i;
			break;
		}
	}
	dfs(0,root);
	printf("%.1lf\n",res);
	return 0;
}

1080 Graduate Admission (30 分)

算法标签: 模拟 + 排序

#include<bits/stdc++.h>
using namespace std;
int cruit_num[105];
struct student{
	int GE;
	int GI;
	int final;
	int rank;
	int choice[5]; 
	int id;
};
student stu[40005];
int choice[105][40005];
int cnt[105];

bool cmp(student s1,student s2){
	if(s1.final!=s2.final){
		return s1.final > s2.final;
	}else{
		return s1.GE > s2.GE;
	}
}

int main(){
	int N,M,K;
	scanf("%d%d%d",&N,&M,&K);
	for(int i=0;i<M;i++){
		scanf("%d",&cruit_num[i]);
	}
	for(int i=0;i<N;i++){
		scanf("%d%d",&stu[i].GE,&stu[i].GI);
		stu[i].final = stu[i].GE + stu[i].GI;
		for(int j=0;j<K;j++){
			scanf("%d",&stu[i].choice[j]);
		}
		stu[i].id = i;
	}
	sort(stu,stu+N,cmp);
	stu[0].rank = 1;
	for(int i=1;i<N;i++){
		if(stu[i].final == stu[i-1].final && stu[i].GE == stu[i-1].GE){
			stu[i].rank = stu[i-1].rank;
		}else{
			stu[i].rank = i+1;
		}
	}

	for(int i=0;i<N;i++){
		for(int j=0;j<K;j++){
			int id = stu[i].choice[j]; 
			if(cruit_num[id]>0){
				cruit_num[id]--;
				choice[id][cnt[id]++] = i;
				break;
			}else if(cruit_num[id]==0 && cnt[id]>0 
			&& stu[choice[id][cnt[id]-1]].rank == stu[i].rank){
				choice[id][cnt[id]++] = i;
				break;
			}
		}
	}
	for(int i=0;i<M;i++){
		if(cnt[i]>0){
			for(int j=0;j<cnt[i];j++){
				choice[i][j] = stu[choice[i][j]].id;
			}
		}
	}
	for(int i=0;i<M;i++){
		sort(choice[i],choice[i]+cnt[i]); 
	}
	
	for(int i=0;i<M;i++){
		if(cnt[i]>0){
			for(int j=0;j<cnt[i];j++){
				if(j==0){
					printf("%d",choice[i][j]);
				}else{
					printf(" %d",choice[i][j]);
				}
			}	
		}
		printf("\n");
	}
	return 0;
}

1081 Rational Sum (20 分)

算法标签: 模拟 + 分数类

#include<bits/stdc++.h>
using namespace std;

struct fraction{
	long long up;
	long long down;
};
fraction f[105];

long long gcd(long long a,long long b){
	if(a<b){
		swap(a,b);
	}
	if(b==0){
		return a;
	}else{
		return gcd(b,a%b);
	} 
}

fraction Reduction(fraction f1){
	if(f1.down<0){
		f1.up = -f1.up;
		f1.down = -f1.down;
	}
	if(f1.up == 0){
		f1.down = 1;
	}else{
		long long g = gcd(abs(f1.up),abs(f1.down));
		f1.down /= g;
		f1.up /= g;	
	}
	return f1;
}

fraction Add(fraction f1,fraction f2){
	fraction res;
	res.down = f1.down*f2.down;
	res.up = f1.down*f2.up + f2.down*f1.up;
	res = Reduction(res);
	return res;
}

int main(){
	int n;
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		scanf("%lld/%lld",&f[i].up,&f[i].down);
		f[i] = Reduction(f[i]);
	}
	fraction sum;
	
	sum.up = 0;
	sum.down = 1;
	
	for(int i=0;i<n;i++){
		sum = Add(sum,f[i]);
	}
	if(sum.down == 1){
		printf("%lld\n",sum.up);
	}else if(sum.up>sum.down){
		printf("%lld %lld/%lld\n",sum.up/sum.down,sum.up%sum.down,sum.down);
	}else{
		printf("%lld/%lld\n",sum.up,sum.down);
	}
	
	return 0;
}

1082 Read Number in Chinese (25 分)

算法标签: 模拟 + 字符串
注意点: 一道好题!

#include<bits/stdc++.h>
using namespace std;
string out[] = {"","Shi","Bai","Qian","Wan","Yi"};
string digit[] = {"ling","yi","er","san","si","wu","liu","qi","ba","jiu"};
int main(){
	int n;
	cin >> n;
	if(n<0){
		cout << "Fu ";
	}
	n = abs(n);
	
	if(n==0){
		cout << "ling" << endl;
		return 0;
	}
	
	char str[15];
	sprintf(str,"%d",n);
	int len = strlen(str);
	int left = 0;
	int right = len-1;
	
	while(left+4<=right){
		right -= 4;
	}
	
	while(left<len){
		bool f = false;
		while(left<=right){
			if(str[left] == '0'){
				f = true;
			}else{
				if(f){
					cout << " ling";
					f = false;
				}
				
				if(left>0){
					cout << " " << digit[str[left]-'0'];
				}else{
					cout << digit[str[left]-'0'];
				}
				
				if(right!=left){
					cout << " " << out[right-left];
				}
			}
			left++;
		}
		int k = (len-left)/4 + 3;
		if(left!=len){
			cout << " " << out[k];
		}
		right += 4;
	}
	
	return 0;
}

1083 List Grades (25 分)

算法标签: 模拟 + 排序

#include<bits/stdc++.h>
using namespace std;
struct student{
	char name[15];
	char course[15];
	int score;
};
const int maxn = 1e4+5;
student s[maxn];
bool cmp(student s1,student s2){
	return s1.score > s2.score;
}
int main(){
	int N;
	scanf("%d",&N);
	for(int i=0;i<N;i++){
		scanf("%s%s%d",s[i].name,s[i].course,&s[i].score);
	}
	int s1,e1;
	scanf("%d%d",&s1,&e1);
	sort(s,s+N,cmp);
	if(s1>e1){
		swap(s1,e1);
	}
	int cnt = 0;
	for(int i=0;i<N;i++){
		if(s[i].score>=s1 && s[i].score<=e1){
			cnt++;
			printf("%s %s\n",s[i].name,s[i].course);
		}
	}
	if(!cnt){
		printf("NONE\n");
	}
	return 0;
}

1084 Broken Keyboard (20 分)

算法标签: 模拟 + 字符串

#include<bits/stdc++.h>
using namespace std;
int a[55];
int isUpper(char c){
	if(c>='A' && c<='Z'){
		return 1;
	}else{
		return 0;
	} 
}

int isdigit(char c){
	if(c>='0' && c<='9'){
		return 1;
	}else{
		return 0;
	}
}

int isLower(char c){
	if(c>='a' && c<='z'){
		return 1;
	}else{
		return 0;
	}
}

int main(){
	string s1,s2;
	cin >> s1 >> s2;
	int j=0;
	for(int i=0;i<s1.size();i++){
		if(s1[i]!=s2[j]){
			if(s1[i]=='_'){
				if(!a[10]){
					a[10] = 1;
					cout << s1[i];	
				}
			}else if(isdigit(s1[i])){
				if(!a[s1[i]-'0']){
					a[s1[i]-'0'] = 1;
					cout << s1[i];
				}
			}else if(isLower(s1[i])){
				if(!a[11+s1[i]-'a']){
					a[11+s1[i]-'a'] = 1;
					char alpha = s1[i] - 'a' + 'A';
					cout << alpha;
				}
			}else if(isUpper(s1[i])){
				if(!a[11+s1[i]-'A']){
					a[11+s1[i]-'A'] = 1;
					cout << s1[i]; 
				} 
			}
		}else{
			j++;
		}
	}
	
	return 0;
}

1085 Perfect Sequence (25 分)

算法标签: 双指针
注意点: 令指针i指向序列头,指针j指向a[i]*p,统计j到i的最大值,由于指针的顺序性,因此总体复杂度为 O ( n l o g n ) O(nlogn) O(nlogn)

#include "iostream"
#include "string"
  
#include "algorithm"
  
using namespace std;
  
int main(){
  
    int N,maxCount=1;
    double p,a[100010];
  
    scanf("%d %lf",&N,&p);
    for (int i=0;i<N;i++)
    {
        scanf("%lf",&a[i]);
    }
    sort(a,a+N);
    for(int i=0;i<N;i++){
        double beginNum=a[i];
        for(int j=i+maxCount;j<N;j++){
            double endNum=a[j];
            if(beginNum*p<endNum){
                break;
            }
            if (j-i+1>maxCount)
            {
                maxCount=j-i+1;
            }
        }
    }
    cout<<maxCount;
}

1086 Tree Traversals Again (25 分)

算法标签: 树,二叉树 + DFS
注意点: 参考P1021/P1053/P1079,解法相同

#include<bits/stdc++.h>
using namespace std;
int pre[105];
int in[105];
int post[105];

stack<int> s;
struct node{
	int data;
	node* lchild;
	node* rchild;
};
node* root = NULL;
node* newNode(int v){
	node* Node = new node;
	Node->data = v;
	Node->lchild = NULL;
	Node->rchild = NULL; 
	return Node;
}
node* Create(int preL,int preR,int inL,int inR){
	if(preL>preR){
		return NULL;
	}
	node* Node = newNode(pre[preL]);
	int k;
	for(int i=inL;i<=inR;i++){
		if(in[i]==Node->data){
			k = i;
			break;
		}
	}
	int numleft = k-inL;
	Node->lchild = Create(preL+1,preL+numleft,inL,k-1);
	Node->rchild = Create(preL+numleft+1,preR,k+1,inR);
	return Node;
}
int cnt3 = 0;
void postorder(node* root){
	if(root==NULL){
		return;
	}
	postorder(root->lchild);
	postorder(root->rchild);
	
	if(cnt3==0){
		printf("%d",root->data);
	}else{
		printf(" %d",root->data);
	}
	cnt3++;
}
int main(){
	int N;
	int cnt1 = 0;
	int cnt2 = 0;
	cin >> N;
	for(int i=0;i<2*N;i++){
		string s1;
		cin >> s1;
		if(s1=="Push"){
			int t;
			cin >> t;
			pre[cnt1++] =  t;
			s.push(t);
		}else{
			in[cnt2++] = s.top();
			s.pop();
		}
	}
	root = Create(0,N-1,0,N-1);
	postorder(root);
	
	return 0;
} 

1087 All Roads Lead to Rome (30 分)

算法标签: 图论 + Dijkstra + DFS
注意点: 参考P1003/P1018/P1030/P1072,解法相同

#include<bits/stdc++.h>
using namespace std;

int N,K;
string city1;
map<string,int> strtonum;
map<int,string> numtostr;

int w[205];
int weight[205];
int num[205];
int D;
bool vis[205];
int dp[205];
int cnt[205];
int pre[205];

struct node{
	int dis;
	int v;
};
vector<node> G[205];

void dfs(int v){
	if(v == 0){
		cout << numtostr[v];
		return;
	} 
	dfs(pre[v]);
	printf("->");
	cout << numtostr[v];
} 
void dijstra(int s){
	memset(vis,0,sizeof(vis));
	fill(dp,dp+N,INT_MAX);
	fill(num,num+N,1);
	dp[s] = 0;
	for(int i=0;i<N;i++){
		int u = -1;
		int minnum = INT_MAX;
		for(int j=0;j<N;j++){
			if(!vis[j] && dp[j]<minnum){
				minnum = dp[j];
				u = j;
			}
		}
		vis[u] = true;
		for(int j=0;j<G[u].size();j++){
			int v = G[u][j].v;
			int dis = G[u][j].dis;
			if(!vis[v]){
				if(dp[u]+dis<dp[v]){
					dp[v] = dp[u]+dis;
					num[v] = num[u];
					weight[v] = weight[u] + w[v];
					cnt[v] = cnt[u] + 1;
					pre[v] = u;
				}else if(dp[u]+dis==dp[v]){
					num[v] += num[u];
					if(weight[v]<weight[u]+w[v]){
						weight[v] = weight[u] + w[v];
						cnt[v] = cnt[u] + 1;
						pre[v] = u;
					}else if(weight[v]==weight[u]+w[v]){
						if(cnt[v]>cnt[u]+1){
							cnt[v] = cnt[u]+1;
							pre[v] = u;
						}
					}
				}
			}
		}
	}
}
int main(){
	cin >> N >> K >> city1;
	strtonum[city1] = 0;
	numtostr[0] = city1;
	for(int i=1;i<=N-1;i++){
		string t;
		cin >> t;
		cin >> w[i];
		if(t=="ROM"){
			D = i;
		}
		strtonum[t] = i;
		numtostr[i] = t;
	}
	
	for(int i=0;i<K;i++){
		string c1,c2;
		int dis;
		cin >> c1 >> c2 >> dis;
		node temp;
		int n1 = strtonum[c1];
		int n2 = strtonum[c2];
		
		temp.v = n2;
		temp.dis = dis;
		G[n1].push_back(temp);
		temp.v = n1;
		G[n2].push_back(temp);
	}
	dijstra(0);
	printf("%d %d %d %d\n",num[D],dp[D],weight[D],weight[D]/cnt[D]);
	dfs(D);
	return 0;
} 

1088 Rational Arithmetic (20 分)

算法标签: 模拟 + 数论

#include<bits/stdc++.h>
using namespace std;
long long gcd(long long a,long long b){
	long long tmp;
	if(a<b){
		tmp = a;
		a = b;
		b = tmp;
	}
	return a%b? gcd(b,a%b) : b;
}
long long lcd(long long a,long long b){
	long long g = gcd(a,b);
	return(1LL*(a/g)*(b/g));
}

void process(long long a,long long b,int T){
	bool flag = false,flag1 = false,flag2=false;
	if(a<0){
		flag1 = true;
	}
	if(b<0){
		flag2 = true;
	}
	if(flag1 && flag2){
		a = -a;
		b = -b;
		flag = false;
	}else if(flag1 && !flag2){
		a = -a;
		flag = true;
	}else if(!flag1 && flag2){
		b = -b;
		flag = true;
	}
	if(a==0 && b!=0){
		cout << "0";
	}else if(b==0 && T==1){
		cout << "Inf";
	}else{
		long long g = gcd(a,b);
		a = a/g;
		b = b/g;
		if(flag){
			cout << "(-";
		}
		if(a>=b){
			int p = a/b;
			int q = a%b;
			if(q!=0){
				cout << p <<" " << q << "/" << b;
			}else{
				cout << p ;
			}
		}else{
			cout << a << "/" << b;
		}
		if(flag){
			cout <<")";
		}
	}
}

int main(){
	char str1[50],str2[50];
	cin >> str1 >> str2;
	long long a,b,c,d;
	sscanf(str1,"%lld/%lld",&b,&a);
	sscanf(str2,"%lld/%lld",&d,&c);

	long long plus1 = b*c + a*d;
	long long plus2 = a*c;
	long long minus1 = b*c - a*d;
	long long minus2 = a*c;
	long long mutl1 = b*d;
	long long mutl2 = a*c;
	long long div1 = b*c;
	long long div2 = a*d;
	process(b,a,0);
	cout << " + " ;
	process(d,c,0);
	cout << " = " ;
	process(plus1,plus2,0);
	cout << endl;
	process(b,a,0);
	cout << " - " ;
	process(d,c,0);
	cout << " = " ;
	process(minus1,minus2,0);
	cout << endl;
	process(b,a,0);
	cout << " * " ;
	process(d,c,0);
	cout << " = " ;
	process(mutl1,mutl2,0);
	cout << endl;
	process(b,a,0);
	cout << " / " ;
	process(d,c,0);
	cout << " = " ;
	process(div1,div2,1);
	cout << endl;
	return 0;
} 

1089 Insert or Merge (25 分)

算法标签: 模拟 + 排序
注意点: 要判断是插入排序还是归并排序(或是P1098中的堆排序),我们需要对每个排序过程十分清晰,插入排序是指有一个序列,每次从前往后将一个无序的元素插入到有序的数列中,因此,插入排序必定是前半部分有序,后半部分无序且和输入的序列一致;接下来看看归并排序,归并排序是两两一组合并,因此我们假设数据元素的位置为i,那么第n轮排序,元素必定位于 i 2 n + [ 2 n , 2 n + 1 ] \frac{i}{2^n}+[2^n,2^{n+1}] 2ni+[2n,2n+1]之间;最后看堆排序,先建堆,然后每一轮堆排序都是上滤的过程,不断交换子结点与父结点

#include<bits/stdc++.h>
using namespace std;
int N;
const int maxn = 1e2+5;
int a[maxn];
int b[maxn];

int main(){
	cin >> N;
	for(int i=0;i<N;i++){
		cin >> a[i];
	}
	for(int i=0;i<N;i++){
		cin >> b[i];
	}
	
	int j=0;
	while(j<N-1 && b[j]<=b[j+1]){
		j++;
	}
	int site1 = j;
	j++;
	while(j<N && a[j]==b[j]){
		j++;
	}
	if(j==N){
		cout << "Insertion Sort" << endl;
		sort(b,b+site1+2);
		for(int i=0;i<N;i++){
			if(i!=N-1){
				cout << b[i] << " ";
			}else{
				cout << b[i];
			}
		}
	}else{
		cout <<"Merge Sort" << endl;
		int k = 1;
		while(1){
			k *= 2;
			for(int i=0;i<N-N%k;i+=k){
				sort(a+i,a+i+k);
			}	
			sort(a+N-N%k,a+N);
			bool flag = true;
			for(int i=0;i<N;i++){
				if(a[i]!=b[i]){
					flag = false;
					break;
				}
			}
			if(flag){
				break;
			}
		}
		k *= 2;
		for(int i=0;i<N-N%k;i+=k){
			sort(a+i,a+i+k);
		}	
		sort(a+N-N%k,a+N);
		for(int i=0;i<N;i++){
			if(i!=N-1){
				cout << a[i] << " ";
			}else{
				cout << a[i];
			}
		}
		
	}
	return 0;
}

1090 Highest Price in Supply Chain (25 分)

算法标签: 树,二叉树 + DFS
注意点: 参考P1021/P1053/P1079/P1086,解法相同

#include<bits/stdc++.h>
using namespace std;
int N;
double P;
double r;
const int maxn = 1e5+5;
int a[maxn];
struct node{
	int data;
	vector<int> child;
};
node n[maxn];

int index_num = 0;
int newnode(int v){
	n[index_num].data = v;
	return index_num++;
}
int maxnum = 0;
int maxdepth = -1;

void dfs(int depth,int now){
	if(n[now].child.size()==0){
		if(depth>maxdepth){
			maxdepth=depth;
			maxnum = 1;
		}else if(depth==maxdepth){
			maxnum++;
		}
		return;
	}
	for(int i=0;i<n[now].child.size();i++){
		dfs(depth+1,n[now].child[i]);
	}
}

int main(){
	cin >> N >> P >> r;
	for(int i=0;i<N;i++){
		scanf("%d",&a[i]);
	}
	int root;
	for(int i=0;i<N;i++){
		int now = newnode(i);
		if(a[now]!=-1){
			n[a[now]].child.push_back(now);
		}else{
			root = now;
		}
	}
	dfs(0,root);
	double res = P*pow(1+r/100.0,maxdepth);
	printf("%.2lf %d\n",res,maxnum);
	return 0;
}

1091 Acute Stroke (30 分)

算法标签: BFS
注意点: 这道题是一道BFS模板题,由于三维方块有6个方向,因此BFS可遍历的宽度为6,每次BFS时需判断是否出界、是否访问过,BFS是队列结构,初始队列内为开始访问的起点,整个队列全部为空时结束BFS的访问

#include<bits/stdc++.h>
using namespace std;
bool f[1350][135][65];
int a[1350][135][65];
int M,N,L,T;
int xx[]={0,0,1,0,0,-1};
int yy[]={0,1,0,0,-1,0};
int zz[]={1,0,0,-1,0,0};
struct node{
	int x,y,z;
};
node temp;
queue<node> q;

int check(int x,int y,int z){
	if(x>=1 && x<=M && y>=1 && y<=N && z>=1 && z<=L){
		return 1;
	}else{
		return 0;
	}
}

int BFS(){
	int cnt = 0;
	while(!q.empty()){
		node front_node = q.front();
		q.pop();
		cnt++;
		for(int i=0;i<6;i++){
			temp.x = front_node.x + xx[i];
			temp.y = front_node.y + yy[i];
			temp.z = front_node.z + zz[i];
			if(check(temp.x,temp.y,temp.z) && 
			!f[temp.x][temp.y][temp.z] && 
			a[temp.x][temp.y][temp.z]==1){
				f[temp.x][temp.y][temp.z] = 1;
				q.push(temp);
			}
		}
	} 
	
	if(cnt>=T){
		return cnt;	
	}else{
		return 0;
	}
}
int main(){
	cin >> M >> N >> L >> T;
	for(int z=1;z<=L;z++){
		for(int x=1;x<=M;x++){
			for(int y=1;y<=N;y++){
				scanf("%d",&a[x][y][z]);
			}
		}
	}
	int ans = 0;
	for(int z=1;z<=L;z++){
		for(int x=1;x<=M;x++){
			for(int y=1;y<=N;y++){
				if(a[x][y][z] == 1 && !f[x][y][z]){
					temp.x = x;
					temp.y = y;
					temp.z = z;
					f[x][y][z] = 1;
					q.push(temp);
					ans += BFS();
				}
			}
		}
	}
	cout << ans << endl;
	return 0;
}

1092 To Buy or Not to Buy (20 分)

算法标签: 模拟 + 字符串

#include<bits/stdc++.h>
using namespace std;
string str1,str2;
int a[105];
int b[105];
int isupper(char c){
	if(c>='A' && c<='Z'){
		return 1;
	}else{
		return 0;
	}
}
int islower(char c){
	if(c>='a' && c<='z'){
		return 1;
	}else{
		return 0;
	}
}
int isdigit(char c){
	if(c>='0' && c<='9'){
		return 1;
	}else{
		return 0;
	}
}
int main(){
	cin >> str1 >> str2;
	for(int i=0;i<str1.size();i++){
		if(isdigit(str1[i])){
			a[str1[i]-'0']++;
		}else if(isupper(str1[i])){
			a[str1[i]-'A'+10]++;
		}else if(islower(str1[i])){
			a[str1[i]-'a'+40]++;
		}
	}
	for(int i=0;i<str2.size();i++){
		if(isdigit(str2[i])){
			b[str2[i]-'0']++;
		}else if(isupper(str2[i])){
			b[str2[i]-'A'+10]++;
		}else if(islower(str2[i])){
			b[str2[i]-'a'+40]++;
		}
	}
	bool flag = true;
	int rest = 0;
	int count1=0,count2=0;
	for(int i=0;i<100;i++){
		count1 += a[i];
		count2 += b[i];
		if(a[i]<b[i]){
			flag = false;
			rest += (b[i]-a[i]);
		}
	}
	if(flag==false){
		cout << "No ";
		cout << rest << endl;
	}else{
		cout << "Yes ";
		cout << count1-count2 << endl;
	}
	return 0;
}

1093 Count PAT’s (25 分)

算法标签: DP
注意点: 把字符串分成3个部分,left/mid/right,若mid=‘A’,那么这个点处PAT的数量等于 l e f t ( P ) ∗ r i g h t ( T ) left(P)*right(T) left(P)right(T),因此 ∑ \sum 累加即可

#include<bits/stdc++.h>
using namespace std;
const long long M = 1000000007;
long long result;
const int maxn = 1e5+5;
string str;


int main(){
	cin >> str;
	int Tcount = 0;
	int Pcount = 0;
	for(int i=0;i<str.size();i++){
		if(str[i]=='T'){
			Tcount++;
		}
	}
	
	for(int i=0;i<str.size();i++){
		if(str[i]=='T'){
			Tcount--;
		}else if(str[i]=='P'){
			Pcount++;
		}else if(str[i]=='A'){
			result = (result + Tcount*Pcount)%M;
		}
	}
	cout << result << endl;
	return 0;
}

1094 The Largest Generation (25 分)

算法标签: 树,二叉树 + DFS
注意点: 建树,做DFS遍历,统计每一层上的结点数,输出最大值及其层号

#include<bits/stdc++.h>
using namespace std;

int N,M;
int a[105];
vector<int> child[105];
int maxdepth = -1;

void dfs(int depth,int root){
	a[depth]++;
	if(depth>maxdepth){
		maxdepth = depth;
	}	
	for(int i=0;i<child[root].size();i++){
		dfs(depth+1,child[root][i]);
	}
}

int main(){
	memset(a,0,sizeof(a));
	cin >> N >> M;
	for(int i=0;i<M;i++){
		int id;
		cin >> id;
		int k;
		cin >> k;
		for(int j=0;j<k;j++){
			int t;
			cin >> t;
			child[id].push_back(t);
		}
	}	
	int root=1;
	dfs(1,root);
	
	int site;
	int maxnum =-1;
	
	for(int i=1;i<=maxdepth;i++){
		if(a[i]>maxnum){
			maxnum = a[i];
			site = i;
		}
	}
	
	printf("%d %d\n",maxnum,site);
	return 0;
}

1095 Cars on Campus (30 分)

算法标签: 大模拟 + 排序

#include<bits/stdc++.h>
using namespace std;
struct record{
	char id[9];
	int time;
	bool status;
};
const int maxn = 1e4+5;
record r[maxn];
record valid[maxn];
int a[maxn];
map<string,int> mp;

bool cmp(record r1,record r2){
	if(strcmp(r1.id,r2.id)!=0){
		return strcmp(r1.id,r2.id)<0;
	}else{
		return r1.time < r2.time;
	}
}

bool cmp1(record r1,record r2){
	return r1.time < r2.time;
}

int main(){
	int N,K;
	scanf("%d%d",&N,&K);
	for(int i=0;i<N;i++){
		int h,m,s;
		char status[10];
		scanf("%s%d:%d:%d%s",r[i].id,&h,&m,&s,status);
		r[i].time = h*3600 + m*60 + s;
		if(strcmp(status,"in")==0){
			r[i].status = 1;
		}else{
			r[i].status = 0;
		}
	} 
	sort(r,r+N,cmp);
	int cnt = 0;
	for(int i=0;i<N;i++){
		if(strcmp(r[i].id,r[i+1].id)==0){
			if(r[i].status == 1 && r[i+1].status == 0){
				strcpy(valid[cnt].id,r[i].id);
				valid[cnt].time = r[i].time;
				valid[cnt].status = r[i].status;
				cnt++;
				strcpy(valid[cnt].id,r[i+1].id);
				valid[cnt].time = r[i+1].time;
				valid[cnt].status = r[i+1].status;
				cnt++;
				mp[r[i].id] += (r[i+1].time-r[i].time);
			}
		}
	}
	sort(valid,valid+cnt,cmp1);
	int index = 0;
	int count = 0;
	for(int i=0;i<K;i++){
		int h,m,s;
		scanf("%d:%d:%d",&h,&m,&s);
		int time = h*3600 + m*60 + s;
		while(valid[index].time<=time && index<cnt){
			if(valid[index].status == 1){
				count++;
			}else{
				count--;
			}
			index++;
		}
		printf("%d\n",count);
	}
	int maxmum = -1;
	for(auto it=mp.begin();it!=mp.end();it++){
		if(it->second>maxmum){
			maxmum = it->second;
		}
	}
	int res;
	for(auto it=mp.begin();it!=mp.end();it++){
		if(it->second == maxmum){
			printf("%s ",it->first.c_str());
			res = it->second;
		}
	}
	printf("%02d:%02d:%02d\n",res/3600,res/60%60,res%60);
	return 0;
} 

1096 Consecutive Factors (20 分)

算法标签: 数论

#include<bits/stdc++.h>
using namespace std;

int main(){
	long long n;
	scanf("%lld",&n);
	int maxlen = -1;
	int site;
	for(int i=2;i<=sqrt(n);i++){
		long long tmp = n;
		int j=i;
		while(1){
			if(tmp%j==0){
				tmp/=j;
				j++;
			}else{
				break;
			}
		}
		if(j-i>maxlen && j!=i){
			maxlen = j-i;
			site = i;
		}
	}
	if(maxlen==-1){
		printf("1\n");
		printf("%lld\n",n);
	}else{
		printf("%d\n",maxlen);
		for(int i=site;i<site+maxlen;i++){
			if(i==site){
				printf("%d",i);
			}else{
				printf("*%d",i);
			}
		}
		printf("\n");
	}
	return 0;
}

1097 Deduplication on a Linked List (25 分)

算法标签: 模拟 + 链表

#include<bits/stdc++.h>
using namespace std;
struct node{
	int value;
	int next;
};
const int maxn = 1e5+5;
node n[maxn];

int ori_add[maxn];
int ori_value[maxn];
int post_add[maxn];
int post_value[maxn];
int cnt1 = 0;
int cnt2 = 0;
set<int> s;

int main(){
	int start;
	int N;
	cin >> start >> N;
	for(int i=0;i<N;i++){
		int y;
		scanf("%d",&y);
		scanf("%d%d",&n[y].value,&n[y].next);
	}
	while(start!=-1){
		if(s.find(abs(n[start].value))!=s.end()){
			post_add[cnt2] = start;
			post_value[cnt2] = n[start].value;
			cnt2++; 
		}else{
			ori_add[cnt1] = start;
			ori_value[cnt1] = n[start].value;
			s.insert(abs(n[start].value));
			cnt1++;
		}
		start = n[start].next;
	} 
	for(int i=0;i<cnt1;i++){
		if(i!=cnt1-1){
			printf("%05d %d %05d\n",ori_add[i],ori_value[i],ori_add[i+1]);
		}else{
			printf("%05d %d -1\n",ori_add[i],ori_value[i]);
		}
	}
	for(int i=0;i<cnt2;i++){
		if(i!=cnt2-1){
			printf("%05d %d %05d\n",post_add[i],post_value[i],post_add[i+1]);
		}else{
			printf("%05d %d -1\n",post_add[i],post_value[i],post_add[i+1]);
		}
	}
	return 0;
} 

1098 Insertion or Heap Sort (25 分)

算法标签: 模拟 + 排序
注意点: 可参考P1089的解法

#include<bits/stdc++.h>
using namespace std;
int res[105];
int a[105];
int b[105];
int c[105];
int N;
int equal(int a[],int b[]){
	int f = 1;
	for(int i=0;i<N;i++){
		if(a[i]==b[i]){
			continue;
		}else{
			f = 0;
			break;
		}
	}
	return f;
}

void insertionsort(int a[],int res[]){
	for(int i=1;i<=N;i++){
		sort(a+1,a+i+1);
		int f = equal(a,res);
		if(i!=1 && f){
			sort(a+1,a+i+2);
			printf("Insertion Sort\n");
			for(int j=1;j<=N;j++){
				if(j==1){
					printf("%d",a[j]);
				}else{
					printf(" %d",a[j]); 
				}
			}
			printf("\n");
			break;
		}
	}
}

void down(int left,int right){
	int i = left;
	int j = 2*i;
	while(j<=right){
		if(j+1<=right && c[j+1]>c[j]){
			j = j+1;
		}
		if(c[i]<c[j]){
			swap(c[j],c[i]);
			i = j;
			j = 2*i;
		}else{
			break;
		}
	}
}

void heapsort(int a[],int res[]){
	for(int i=N/2;i>=1;i--){
		down(i,N);
	}
	for(int i=N;i>=1;i--){
		swap(a[1],a[i]);
		down(1,i-1);
		int f = equal(a,res);
		if(f){
			printf("Heap Sort\n");
			swap(a[1],a[i-1]);
			down(1,i-2);
			for(int j=1;j<=N;j++){
				if(j==1){
					printf("%d",a[j]); 
				}else{
					printf(" %d",a[j]);
				}
			}
			printf("\n");
			break;
		}
	}
}
int main(){
	
	scanf("%d",&N);
	for(int i=1;i<=N;i++){
		scanf("%d",&a[i]);
		b[i] = a[i];
		c[i] = a[i];
	}
	for(int i=1;i<=N;i++){
		scanf("%d",&res[i]);
	}
	insertionsort(b,res);
	heapsort(c,res);
	
	return 0;
} 

1099 Build A Binary Search Tree (30 分)

算法标签: 树,二叉树 + 遍历
注意点: 先建树,然后执行中序遍历和层序遍历

#include<bits/stdc++.h>
using namespace std;
int N;
int a[105];

struct node{
	int data;
	int lchild=-1;
	int rchild=-1;
};
node tree[105];
int cnt = 0;

void InOrder(int root){
	if(root==-1){
		return;
	}
	InOrder(tree[root].lchild);
	tree[root].data = a[cnt++];
	InOrder(tree[root].rchild);
}
int res = 0;
void LevelOrder(int root){
	queue<int> q;
	q.push(root);
	while(!q.empty()){
		int f = q.front();
		q.pop();
		res++;
		if(res ==1){
			printf("%d",tree[f].data);
		}else{
			printf(" %d",tree[f].data);
		}
		if(tree[f].lchild!=-1){
			q.push(tree[f].lchild);
		}
		if(tree[f].rchild!=-1){
			q.push(tree[f].rchild);
		}
	}
	printf("\n");
}

int main(){
	cin >> N;
	for(int i=0;i<N;i++){
		int l,r;
		cin >> l >> r;
		if(l==-1){
			tree[i].lchild = -1;
		}else{
			tree[i].lchild = l;
		}
		if(r==-1){
			tree[i].rchild = -1;
		}else{
			tree[i].rchild = r;
		}
	}	
	for(int i=0;i<N;i++){
		cin >> a[i];
	}
	sort(a,a+N);
	InOrder(0);
	LevelOrder(0);
	
	return 0;
}

1100 Mars Numbers (20 分)

算法标签: 模拟 + 字符串

#include<bits/stdc++.h>
using namespace std;
string D[13] = {"tret","jan", "feb", "mar", "apr", "may", "jun", "jly", "aug", "sep", "oct", "nov", "dec"};
string G[13] = {"","tam", "hel", "maa", "huh", "tou", "kes", "hei", "elo", "syy", "lok", "mer", "jou"};
int isdigit(char c){
	if(c>='0' && c<='9'){
		return 1;
	}else{
		return 0;
	}
}
int iscase(char c){
	if(c>='a' && c<='z'){
		return 1;
	}else{
		return 0;
	}
}
int main(){
	int N;
	cin >> N;
	string s;
	getline(cin,s);
	
	for(int i=0;i<N;i++){
		string str;
		getline(cin,str);
		int num = 0;
		if(isdigit(str[0])){
			for(int i=0;i<str.size();i++){
				num = num *10 + str[i]-'0';
			}
			int g = num / 13;
			int d = num % 13;
			if(g!=0 && d==0){
				cout << G[g] << endl;
			}else if(g!=0 && d!=0){
				cout << G[g] << " "; 
				cout << D[d] << endl;
			}else{
				cout << D[d] << endl;
			}
		}else{
			string s1 = "";
			string s2 = "";
			bool f1 = true;
			for(int i=0;i<str.size();i++){
				if(iscase(str[i]) && f1){
					s1 += str[i];
				}else if(str[i] == ' '){
					f1 = false;
				}else if(iscase(str[i])&& !f1){
					s2 += str[i];
				}
			}
			if(s2 == ""){
				for(int i=0;i<13;i++){
					if(s1 == D[i]){
						cout << i << endl;
						break;
					}
				}
				for(int i=1;i<13;i++){
					if(s1 == G[i]){
						cout << i*13 << endl;
						break;
					}
				}
			}else{
				int g,d;
				for(int i=1;i<13;i++){
					if(s1 == G[i]){
						g = i;
						break;
					}
				}
				for(int i=0;i<13;i++){
					if(s2 == D[i]){
						d = i;
						break;
					}
				}
				cout << g*13 + d << endl;
			}
		}
	}
	
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值