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;
    }
    
  • 相关阅读:
    leetcode -- Triangle
    leetcode difficulty and frequency distribution chart
    leetcode -- Sqrt(x)
    leetcode -- Climbing Stairs
    leetcode -- Populating Next Right Pointers in Each Node II
    leetcode -- Populating Next Right Pointers in Each Node
    ThreadLocal
    Thread
    进程或者线程状态
    ThreadGroup
  • 原文地址:https://www.cnblogs.com/fisherss/p/11615671.html
Copyright © 2011-2022 走看看