zoukankan      html  css  js  c++  java
  • PAT(甲级)2019年秋季考试


    第一题用搜索,超时了,待补

    更新第一题思路
    dfs + 剪枝,首先确定 n的最后一位数字肯定是9,为什么呢,因为 任意两个相邻的数肯定互为质数(gcd=1),所以 n 的末尾肯定是9,这样n+1产生的各个位数和相加的和 才能有可能和sum(n)产生gcd>2的素数,
    所以k可以剪枝成k-1,缩小一位,复杂度降低很多。。。这样估计就能AC了。
    另外判断n和n+1两个数的各个位数之和的gcd是否为大于2的素数,可以提前预处理(数据量<90),
    第一题参考链接

    7-1搜索 12/20分


    原来写的代码,超时2个测试点

    #include<bits/stdc++.h>
    using namespace std;
    
    int n,k,m;
    typedef long long ll;
    ll starts = 0;
    ll endss = 0;
    bool flag = false;
    bool first = true;
    int t = 1;
    
    int sums(ll x){
    	int ans = 0;
    	while(x){
    		ans += x%10;
    		x/=10;
    	}
    	return ans;
    }
    
    
    ll gcd(ll a,ll b){
    	if(b == 0) return a;
    	return gcd(b,a%b);
    }
    
    bool solve(ll x){
    	if(x <= 2) return false;
    	for(int i=2;i<=sqrt(x);i++){
    		if(x%i == 0) return false;
    	}
    	return true;
    }
    
    
    void dfs(int step,ll x){
    	if(x >= endss) return;
    	if(step > k+1) return;
    	if(sums(x) > m) return;
    	if(step == k+1) {
    		int t1 = sums(x);
    		if(sums(x) != m) return;
    		int t2 = sums(x+1);
    		ll g = gcd(t1,t2);
    		if(solve(g)){
    			if(first){
    				first = false;
    				cout<<"Case "<<t<<endl;
    			}
    			flag = true;
    			cout<<t2<<" "<<x<<endl;
    		}
    		return;
    	}
    	for(int i=0;i<=9;i++){
    		if(i==0 && step == 1) continue;
    		ll temp = x * 10 + i;
    		dfs(step+1,temp);
    	}
    } 
    
    int main(){
    	cin>>n;
    	for(int i=1;i<=n;i++){
    		cin>>k>>m;
    		starts = pow(10,k-1);
    		endss = pow(10,k);
    		flag = false;	
    		first = true;
    		t = i;
    		dfs(1,0);
    		if(flag == false){
    			cout<<"Case "<<t<<endl;
    			cout<<"No Solution"<<endl;
    		}
    	}
    	return 0;
    }
    

    7-2链表模拟 25

    #include<bits/stdc++.h>
    using namespace std;
    
    const int maxn = 1e5+10;
    
    struct node{
    	int  address;
    	int data;
    	int  next;
    }li[maxn];
    
    int s1,s2;
    int n; //不一定都是有效结点 
    vector<node> v1;
    vector<node> v2;
    vector<node> ans;
    
    int main(){
    	scanf("%d%d%d",&s1,&s2,&n);
    	for(int i=1;i<=n;i++){
    		int dat,add,nex;
    		scanf("%d%d%d",&add,&dat,&nex);
    		li[add].address = add;
    		li[add].data = dat;
    		li[add].next = nex;
    	}
    	for(int cur = s1;cur != -1;cur = li[cur].next) v1.push_back(li[cur]);
    	for(int cur = s2;cur != -1;cur = li[cur].next) v2.push_back(li[cur]);
    	int len1 = v1.size() - 1;
    	int len2 = v2.size() - 1;
    	if(len1 >= 2*len2){
    		reverse(v2.begin(),v2.end());
    		int idx2 = 0;
    		int idx1 = 0;
    		while(idx2 <= len2){
    			ans.push_back(v1[idx1++]);
    			ans.push_back(v1[idx1++]);
    			ans.push_back(v2[idx2++]);
    		}
    		while(idx1 <= len1) ans.push_back(v1[idx1++]);
    	}else{
    		reverse(v1.begin(),v1.end());
    		int idx2 = 0;
    		int idx1 = 0;
    		while(idx1 <= len1){
    			ans.push_back(v2[idx2++]);
    			ans.push_back(v2[idx2++]);
    			ans.push_back(v1[idx1++]);
    		}
    		while(idx2 <= len2) ans.push_back(v2[idx2++]);
    	}
    	n = ans.size();
    	for(int i=0;i<n-1;i++){
    		printf("%05d %d %05d
    ",ans[i].address,ans[i].data,ans[i+1].address);
    	}
    	printf("%05d %d -1
    ",ans[n-1].address,ans[n-1].data);
    	return 0;
    }
    

    7-3树 25

    #include<bits/stdc++.h>
    using namespace std;
    
    struct node{
    	string dat;
    	int lc,rc;
    }tree[25];
    
    int n;
    int vis[25];
    
    void dfs(int x){
    	if(x > n) return;
    	cout<<"(";
    	if(tree[x].lc == -1 &&  tree[x].rc != -1){
    		cout<<tree[x].dat;
    		dfs(tree[x].rc);
    		cout<<")";
    	}else{
    		if(tree[x].lc!=-1) dfs(tree[x].lc);
    		if(tree[x].rc!=-1) dfs(tree[x].rc);
    		cout<<tree[x].dat;
    		cout<<")";
    	}
    }
    
    int main(){
    	cin>>n;
    	for(int i=1;i<=n;i++){
    		cin>>tree[i].dat>>tree[i].lc>>tree[i].rc;
    		if(tree[i].lc != -1) vis[tree[i].lc] = 1;
    		if(tree[i].rc != -1) vis[tree[i].rc] = 1;
    	}
    	int root = 1;
    	for(int i=1;i<=n;i++){ //先确定 根的结点 没有当过 
    		if(!vis[i]) root = i;
    	}
    	dfs(root);
    	return 0;
    }
    

    7-4最短路 30

    #include<bits/stdc++.h>
    using namespace std;
    
    const int inf = 0x3f3f3f3f;
    const int maxn = 1e3+10;
    const int maxm = 1e5+10;
    struct edge{
    	int v;
    	int w;
    	edge(int vv,int ww){
    		v = vv;
    		w = ww;
    	}
    };
    
    vector<edge> g[maxn];
    int n,e,k;
    int di[maxn];
    int dist[maxn];
    int vis[maxn];
    
    bool dijkstra(int s){
    	memset(dist,inf,sizeof(dist));
    	memset(vis,0,sizeof(vis));
    	dist[s] = 0;
    	for(int i=1;i<=n;i++){
    		int v,min_w = inf;
    		for(int j=1;j<=n;j++){
    			if(!vis[j] && dist[j] < min_w){
    				v = j;
    				min_w = dist[j];
    			}
    		}
    		if(min_w == inf) return false;
    		vis[v] = 1;
    		for(int j=0;j<g[v].size();j++){
    			int x = g[v][j].v;
    			int w = g[v][j].w;
    			if(!vis[x] && dist[x] >dist[v] + w){
    				dist[x] = dist[v] + w;
    			}
    		}
    	}
    	return true;
    }
    int vis2[maxn];
    bool solve(){
    	memset(vis2,0,sizeof(vis2));
    	vis2[di[1]] = 1;
    	for(int i=2;i<=n;i++){
    		int mind = inf;
    		for(int j=1;j<=n;j++){
    			if(!vis2[j] && dist[j] <= mind){
    				mind = dist[j];
    			}
    		}
    		if(mind != dist[di[i]]) 
    			return false;
    		vis2[di[i]] = 1;
    	}
    	return true;
    }
    
    
    void solve2(){
    	int visit[n + 1];
    	for (int i = 1; i <= n; i++) visit[i] = 0;
    	int start = di[1];
    	visit[start] = 1;
    	bool flag = false;
    	for (int i = 2; i <= n; i++) {
    		int mine = dist[di[i]];
    		visit[di[i]] = 1;
    		for (int j = 1; j <= n; j++) {
    			if (visit[di[j]]) continue;
    			int curv = dist[di[j]];
    			if (mine >= curv) mine = curv;
    		}
    		if (mine < dist[di[i]]) {
    			cout << "No" << endl;
    			flag = true;
    			break;
    		}
    	}
    	if (flag == false) cout << "Yes" << endl;
    }
    
    int main(){
    	cin>>n>>e;
    	for(int i=1;i<=e;i++){
    		int u,v,w;
    		cin>>u>>v>>w;
    		g[u].push_back(edge(v,w));
    		g[v].push_back(edge(u,w));
    	}
    	cin>>k;
    	for(int i=1;i<=k;i++){
    		for(int j=1;j<=n;j++) cin>>di[j];
    		int st = di[1];
    		dijkstra(st);
    //		solve2();
    		if(solve()){
    			cout<<"Yes"<<endl;
    		}else{
    			cout<<"No"<<endl;
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    yocto/bitbake 学习资源
    QEMU/KVM学习资源
    ubuntu 中创建和删除用户
    git 重命名本地和远程分支
    Ubuntu 上搭建 FTP 服务器
    gdb 常见用法
    git log 显示与特定文件相关的 commit 信息
    基于 qemu system mode 运行 arm 程序
    基于 qemu user mode 运行 aarch64 程序
    checking in(airport)
  • 原文地址:https://www.cnblogs.com/fisherss/p/11615671.html
Copyright © 2011-2022 走看看