20年春季甲級pat考試

Liberalspirit發表於2020-11-25

1.題目連結https://blog.csdn.net/allisonshing/article/details/104213959

#include<cstdio>
#include<string>
#include<iostream>
#include<vector>
#include <algorithm>//fill()在裡面 
#include <cmath>

using namespace std;
//20春季PAT A1 

const int INF=1e9;  
const int maxn=110;

bool isPrime(int x){
	//判斷素數:記住 
	if(x==0||x==1) return false;
	if(x==2)return true;
	int y=(int)sqrt(x*1.0);//double sqrt(double);
	for(int i=2;i<=y;i++){
		if(x%i==0)return false;
	}
	return true;
	 
}
int main(){
//	int date;
//	scanf("%d",&date);
	//每次去掉開頭的一個字母得到的子字串也是素數
	//將數字轉換為int陣列;或者輸入的是string轉換成num
	string date;
	cin>>date;
	int num=stoi(date);
//	cout<<num<<endl;
int len=date.length();
int flag=1;
	for(int i=0;i<len;i++){
//		cout<<date[0]<<endl;
	string str=date.substr(i,len);
	cout<<str;
		int num=stoi(str);
//			cout<<num;
		if(isPrime(num)){
			cout<<" Yes"<<endl;
		}else{
			cout<<" No"<<endl;
			flag=0;//只要有一個不符合則是0 
		}
	} 
	if(flag==1){
		cout<<"All Prime!"<<endl;
	}
	

	
return 0;
} 

2.

#include<cstdio>
#include<string>
#include<iostream>
#include<vector>
#include <algorithm>//fill()在裡面 
#include <cmath>
#include<unordered_set> //注意加上標頭檔案#include<unordered_set>
#include<set> 
#include <cstdlib>//貌似是free,malloc等函式的標頭檔案 

using namespace std;
//20春季PAT A2 
	//給出n個player的m輪的數字,(下標1-n) 
	//從1th人開始給數字 ,淘汰後的選手在之後的遊戲局中該選手給出的數字忽視
	//輸的人或者贏的人不止一個時,按照下標從小到大輸出 
	//出局:輸入重複的數字,或者不是正確的答案 
const int INF=1e9;  
const int maxn=110;

//s儲存正確的數字,oid儲存出局的選手
unordered_set<int>s,oid;//set自動排序比較耗時,unset由於無序所以查詢的快
int data[13][105];
//是否正確 
bool judge(int x){
	//容器使用迭代器的方式進行迴圈
	 //迭代器迴圈變數申明 
	 unordered_set<int>::iterator it=s.begin();//相當於指標 
	 for(;it!=s.end();it++){
	 	if(s.find(*it+x)!=s.end()){
	 		//set的find方法:如果找不到則返回s.end
			 //將引數和s中存在的每個數相加之後的數再去s裡查詢。差值的查詢基本都用這種思路
	//不需要計算所有的正確值:當前的數字一定是當前所加入數字的差值:所以只要找到差值和其餘的值相加= 其餘值中的另一個就行 	 
			 return true;//查重在main中做 
		 }
	 }
	 return false; 
	 
}
int main(){
	int a,b;
	scanf("%d %d",&a,&b);
	s.insert(a);
	s.insert(b);
	int n,m;
	scanf("%d %d",&n,&m);//n:players;m:rounds
	//n:[2,10] m:[2,103]
	//儲存初始資料使用二維陣列?:資料都是正數 
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			scanf("%d",&data[i][j]);//人的下標和比賽輪數的下標都從1開始 
		}
	}
	//每次對列處理 j=1=>j=m 
	for(int j=1;j<=m;j++){
		for(int i=1;i<=n;i++){//已經按下標的順序輸出了 
			if(oid.find(i)!=oid.end())continue;
			int x=data[i][j];
			if(s.find(x)!=s.end()||!judge(x)){
				//如果重複/或者不是當前數字差值--->該玩家出局 
				oid.insert(i);
				printf("Round #%d: %d is out\n",j,i);
			}else{
				s.insert(x);
			}
		}
	}
	 
	 //計算贏家 :只需要查詢oid裡沒有的玩家
	 bool flag=false;//沒有贏家
	 for(int i=1;i<=n;i++){
	 	if(oid.find(i)==oid.end()){
	 		//沒找到 
	 		if(!flag){
	 			//第一次找到的時候flag還是false
				 printf("Winner(s): %d",i); 
			 }else{
			 	 printf(" %d",i);
			 }
	 		flag=true;
		 }
	 } 
	 if(!flag)printf("No winner.");

return 0;
} 

3.A3(過了測試用例,沒測試,考試的時候ac過了但是不知道在官網上的哪裡找我的程式碼。。。)

方法一:

#include<cstdio>
#include<string>
#include<iostream>
#include<vector>
#include <algorithm>//fill()在裡面 
#include <cmath>
#include<unordered_set>
#include<set> 
#include <cstdlib>//貌似是free,malloc等函式的標頭檔案 

using namespace std;
//20春季PAT A3
//動物園有k種動物:分到n個區域:相鄰的兩個區域不能有相同的動物 
//任務:辨別給出的分配方案是否可行
//輸入:n(節點數:區域數(0,500]),r(邊數[0+&)),k(動物種類) :n和k從下標1開始 
//分析:無向圖
 
const int INF=1e9; //fill(map[0],map[0]+maxn*maxn,INF); 
const int maxn=510;
int map[maxn][maxn];//儲存邊關係:右邊則是1,無邊是0 
int plan[maxn];
set<int> visit;//儲存已經輸入過的種類數:利用去重的性質 
 
int main(){
	int n,r,k;
	scanf("%d%d%d",&n,&r,&k);
	int begin,end;
	while(r--){
		scanf("%d%d",&begin,&end);
		map[begin][end]=1;
		map[end][begin]=1;
	} 
	int m;
	scanf("%d",&m);
	while(m--){
		//m個計劃:每個計劃給出種類的n個索引 
		int count=0;//對種類的計數 
		for(int i=1;i<=n;i++){
			//下標從1開始
			scanf("%d",&plan[i]);
			visit.insert(plan[i]);//插入物種		
		}
		count=visit.size();
		
		if(count<k){
			printf("Error: Too few species.\n");
		}else if(count>k){
			printf("Error: Too many species.\n");
		}else{
			//繼續判斷相鄰的區域是否有相同的動物
			//遍歷map?:可以在遍歷的時候減少遍歷數 
			int flag=1;//為了防止列印no多次 
			for(int i=1;i<=n;i++){
				for(int j=1;j<=n;j++){
					if(map[i][j]==1){
						//存在邊的時候判斷兩個區域的動物
						if(plan[i]==plan[j]){
							flag=0;//說明不符合要輸出No 
						}
					}
				}
			} 
			if(flag==1){
				printf("Yes \n");
			}else{
				printf("No\n");
			}
		}
		//清空visit
		visit.clear(); 
			 
	}
	

return 0;
} 

方法二:

#include<cstdio>
#include<string>
#include<iostream>
#include<vector>
#include <algorithm>//fill()在裡面 
#include <cmath>
#include<unordered_set>
#include<set> 
#include <cstdlib>//貌似是free,malloc等函式的標頭檔案 

using namespace std;
//20春季PAT A3

int plan[maxn];
set<int> visit;//儲存已經輸入過的種類數:利用去重的性質 
struct node{
	int a,b;//頭尾節點 
}temp;
vector<node> map;
int main(){
	int n,r,k;
	scanf("%d%d%d",&n,&r,&k);
	while(r--){
		scanf("%d%d",&temp.a,&temp.b);
	//	map.insert(temp);//vector的插入是push_back 
		map.push_back(temp);
	} 
	int m;
	scanf("%d",&m);
	while(m--){
		//m個計劃:每個計劃給出種類的n個索引 
		int count=0;//對種類的計數 
		for(int i=1;i<=n;i++){
			//下標從1開始:沒用變長陣列:用變長陣列也行 vector<int> plan(n+1); 
			//新的C標準好像可以用變數初始化陣列長度 
			scanf("%d",&plan[i]);
			visit.insert(plan[i]);//插入物種		
		}
		count=visit.size();
		
		if(count<k){
			printf("Error: Too few species.\n");
		}else if(count>k){
			printf("Error: Too many species.\n");
		}else{
		//可以直接在最開始使用結構只儲存邊,這樣能減少遍歷的時間以及二維陣列的空間複雜度
		 	int len=map.size();
		 	int flag=1;
			 for(int i=0;i<len;i++){
			 	int x=map[i].a;
			 	int y=map[i].b;
			 	if(plan[x]==plan[y]){
			 		flag=0;
			 		break;
				 }
			 }
			if(flag==1){
				printf("Yes \n");
			}else{
				printf("No\n");
			}
		}
		//清空visit
		visit.clear(); 
			 
	}
	

return 0;
} 

4.A4

#include<cstdio>
#include<string>
#include<iostream>
#include<vector>
#include <algorithm>//fill()在裡面 
#include <cmath>
#include<queue>
#include<unordered_set>
#include<set> 
#include <cstdlib>//貌似是free,malloc等函式的標頭檔案 

using namespace std;
//20春季PAT A4 (模擬題:挺難的) 
//輸入資料太大-->外部排序?置換演算法 :使用有限的記憶體產生一系列的有序記錄(每一次記錄的大小就是記憶體的大小)
//最簡單的策略:每次讀取儘可能多的記錄入記憶體:將這一部分排序,再將排序後的結果寫回磁帶裡 
//排序採用升序:記憶體中只要輸出了一個數字,立馬可以再輸進來一個數字 
//如果下一個數字比輸出的數字大,則可包含在當前的run裡,一遇到比輸出數字小的數字則進入下一個run 
 
const int INF=1e9; //fill(map[0],map[0]+maxn*maxn,INF); 
const int maxn=510;

int main(){
//思路:使用佇列:考試的時候很無語的忘記佇列的用法了	
	int n,m;
	scanf("%d%d",&n,&m);
	
	//n其實還蠻大的,所以直接開陣列不太合適,優先考慮用vector 
	 vector<int> data;
	 int temp;
	 int n1=n;
	 while(n1--){//這裡n變化了 
	 	scanf("%d",&temp);
	 	data.push_back(temp);
	 }
//	 cout<<data.size()<<endl;data如果設定了長度再往裡面填東西好會出問題 
	 //優先佇列的用法!! 
	 priority_queue<int,vector<int>,greater<int> > q;//模擬記憶體的排序
	//greater表示升序排序less表示降序
	//priority_queue< type資料型別, container實現優先佇列的底層容器, function >
	 //分析:要用多少個vector來存放run?run事先不知道
	 //設兩個vector :一個當前的,一個是儲存下一個run的
	 vector<int> current,next;
	 int index=0,count=0;
	 //初始資料輸入 
	 for(;index<m;index++)q.push(data[index]);//為什麼沒有函式提示
	 while(count!=n){
	 	//count計算output的數 ,每次處理一個數 
		int top=q.top();//佇列的頂部元素:優先佇列已經實現升序排序
//		cout<<"top="<<top<<endl; 
		current.push_back(top);
		q.pop();//刪除隊首元素
		count++;//輸出+1
//		cout<<"index="<<index<<"n="<<n<<endl;
		if(index<n){//這時如果data中還有資料,繼續輸入下一個數字
			//下一個輸入的數字和當前輸出的數字比較 
		
			 if(data[index]>=top){//不小於 
			 	q.push(data[index++]);
			 }else{
			 	//放到下一個run裡
				 next.push_back(data[index++]);  
			 }
		}
		//如果本輪的數處理結束:q為空
		if(q.empty()){
			//輸出本輪的run:然後再清空current裡面的數字來儲存下一輪的輸出
			for(int i=0;i<current.size();i++){
				//輸出格式要求:
				if(i!=0)printf(" ");
				printf("%d",current[i]);
			} 
			printf("\n");
			//current清空+將下一輪暫存的資料放入q中排序+next清空 
			current.clear();
			for(int i=0;i<next.size();i++){
				//下一輪的全部放進去??因為下一輪的next得存下一個資料 
				q.push(next[i]); 
			}
			next.clear();	
		} 
	 }
	 
return 0;
} 

 

相關文章