PAT甲级练习(简单)

题一:acwing1502. PAT 排名

编程能力测试(PAT)由浙江大学计算机科学与技术学院组织。

每次测试都会在多个地区同时进行,测试完成后,将会对成绩进行统计与合并,生成总排名。

你的任务就是编写一个程序,将各地区人员的成绩合并汇总,生成最终排名。

输入格式

第一行包含整数 N,表示测试将会在 N 个地区同时进行。

接下来是 N 个地区的成绩列表。

每个地区的成绩列表,第一行包含整数 K,表示该地区的测试人数。

接下来 K行,每行包含一个学生的考号(13 位数字)以及该学生的成绩。

输出格式

第一行输出总考生人数。

然后用以下格式输出最终成绩排名列表:

registration_number final_rank location_number local_rank

也就是输出考号,最终排名,地区编号,地区排名。

地区编号按输入顺序依次为 1∼N。

按照最终排名从前到后的顺序输出每个人的信息。

具有相同分数的人的排名也要相同,相同分数的人,考号较小的先输出。

数据范围

1≤N≤100,
1≤K≤300,
分数在 [0,100] 范围内。

代码:

#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
typedef long long LL;
using namespace std;
const int N = 3e4 + 10;
int n;
int K[105];
struct Per {
	LL s;
	int side;
	int sco;
	int rank;
	int a_rank;
	bool operator<(const Per& P)const
	{
		return sco < P.sco;
	}
};
Per p[105][305];
Per pp[N];
int idx=0;
int main()
{
	cin >> n;
	for (int i = 1;i <= n;i++) {
		int k;
		scanf("%d", &k);
		K[i] = k;
		for (int j = 1;j <= k;j++) {
			scanf("%lld %d", &p[i][j].s, &p[i][j].sco);
			p[i][j].side = i;
		}
	}
	for (int i = 1;i <= n;i++) {
		sort(p[i]+1, p[i] + K[i]+1);
		for (int j = K[i], l = 1;j > 0;j--, l++){
			if (p[i][j].sco == p[i][j + 1].sco) {
			    if(j!=K[i]){
				p[i][j].rank = p[i][j + 1].rank;
			    }else{
			        p[i][j].rank = l;
			    }
			}
			else {
				p[i][j].rank = l;
			}
			pp[++idx] = p[i][j];
		}
	}
	sort(pp+1, pp + idx+1);
	cout << idx << endl;
	for (int i = idx,j=1;i >0;i--,j++) {
		if (pp[i].sco == pp[i + 1].sco) {
		    if(i!=idx){
			pp[i].a_rank = pp[i + 1].a_rank;
		    }else{
		        pp[i].a_rank = j;
		    }
		}
		else {
			pp[i].a_rank = j;
		}
	}
	bool flag = 1;
	while (flag) {
		flag = 0;
		for (int i = 1;i <= idx;i++) {
			if (pp[i].sco == pp[i + 1].sco) {
				if (pp[i].s < pp[i + 1].s) {
					swap(pp[i], pp[i + 1]);
					flag = 1;
				}
			}
		}
	}
	
	
	for (int i = idx;i >0;i--) {
	    
	    if(pp[i].s<1000000000000){
	        int cnt=0;int ss=pp[i].s;
	        while(ss){
	            cnt++;
	            ss=ss/10;
	        }
	        for(int j=1;j<=13-cnt;j++){
	            printf("0");
	        }
	    }
		printf("%lld %d %d %d\n", pp[i].s, pp[i].a_rank, pp[i].side, pp[i].rank);
	}
}

题二:acwing1500. 趣味数字

请注意,数字 123456789 是一个 9 位数字,完全由 1 到 9 组成,没有重复。

将其加倍,我们将获得 246913578,它恰好是另一个 9 位数字,恰好由 1 到 9 组成,只是排列不同。

现在,给定你一个 k 位的数字,请你判断将其加倍以后得到的数字是否可以由原数字的各数位重新排列得到。

输入格式

共一行,包含一个整数。

输出格式

输出共两行

如果原数字的各数位重新排列可以得到加倍后的数字,则在第一行输出 Yes,否则输出 No

第二行,输出加倍后得到的数字。

数据范围

输入数字不超过 20 位。

 代码:

#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
const int N = 25;
char a[N]; 
int b[N];
int s[N];
int cnt[N];
void solve()
{
	cin >> a;
	int la = strlen(a);
	for (int i = 0;i < la;i++) {
		cnt[a[i] - '0']++;
	}
	for (int i = 0;i < la;i++) {
		s[la - i] = a[i] - '0';
	}
	la++;
	for (int i = 1;i <= la;i++) {
		b[i] += (s[i] + s[i]);
		b[i + 1] = b[i] / 10;
		b[i] = b[i] % 10;
	}
	if (b[la] == 0) {
		la--;
	}
	for (int i = la;i > 0;i--) {
		cnt[b[i] ]--;
	}
	int flag = 0;
	for (int i = 0;i<=9;i++) {
		if (cnt[i]) {
			flag = 1;
			break;
		}
	}
	if (flag) {
		printf("No\n");
		for (int i = la;i > 0;i--) {
			printf("%d", b[i]);
		}
	}
	else {
		printf("Yes\n");
		for (int i = la;i > 0;i--) {
			printf("%d", b[i]);
		}
	}
}
int main()
{
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	int T = 1;
	while (T--) {
		solve();
	}
}

题三:acwing1501. 回文数

如果一个数字从前往后读和从后往前读都一样,那么这个数字就是回文数字。

所有一位数字都是回文数字。

非回文数字可以通过一系列的操作与回文数字配对。

首先,将非回文数字反转,让反转后的数字与原数字相加,得到一个新的数字。

如果新的数字不是回文数字,那么就重复此操作,直到得到回文数字为止。

例如,我们从 67 开始,经过两次操作可以得到一个回文数字:67+76=143,143+341=484。

对于给定的任意正整数 N,请你找到它的配对回文数并输出得到该回文数需要的操作次数。

输入格式

共一行,包含两个整数 N 和 K,分别表示给定整数以及最大操作次数。

输出格式

共两行,第一行输出配对回文数。

第二行输出得到配对回文数所需要的操作次数。

如果经过 K 次操作后,仍然无法得到回文数字。

那么,第一行输出 K 次操作后得到的数字。

第二行输出 K。

数据范围

1≤N≤1010
1≤K≤100

 代码:

#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
const int N = 1010;
char s1[N], s2[N];
int a[N], b[N];
int c[N];
int n, k;
int idx, cnt;
void solve()
{
	cin >> s1 >> k;
	int ls = 0;
	idx = k;
	ls=strlen(s1);
	for(int i=1;i<=ls;i++){
	    c[i]=s1[i-1]-'0';
	}
	int f=1;
	for (int i = 1;i <= ls;i++) {
			if (c[i] != c[ls + 1 - i]) {
				f = 0;
				break;
			}

	}
		
	while (k--&&f==0) {
	    
		cnt++;
		if (cnt > 1) {
			for (int i = 1;i <= ls;i++) {
				s1[i - 1] = c[i] + '0';
			}
		}
		//cout << s1 << endl;
		ls = strlen(s1);
		for (int i = 0;i < ls;i++) {
			s2[ls - i - 1] = s1[i];
		}
		//cout << s2 << endl;
		for (int i = ls;i > 0;i--) {
			a[i] = s1[ls - i] - '0';
			b[i] = s2[ls - i] - '0';
		}
		ls++;
		c[1] = 0;
		for (int i = 1 ;i<=ls;i++) {
			c[i] += (a[i] + b[i]);
			c[i + 1] = c[i] / 10;
			c[i] = c[i] % 10;
		}
		while (c[ls] == 0) {
			ls--;
		}
		int flag = 1;
		for (int i = 1;i <= ls;i++) {
			if (c[i] != c[ls + 1 - i]) {
				flag = 0;
				break;
			}

		}
		if (flag) {
			break;
		}
		
	}
	if(cnt!=0){
	for (int i = ls;i > 0;i--) {
	printf("%d", c[i]);

    }	printf("\n");
    
	}else{
	    cout<<s1<<endl;
	}
	printf("%d", cnt);
}
	

int main()
{
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	int T = 1;
	while (T--) {
		solve();
	}
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值