PAT (Basic Level) Practice (中文)题目集合

1001 害死人不偿命的(3n+1)猜想 (15 分)

#include
using namespace std;

int n, ans;
int main()
{
	cin >> n;
	
	while (n != 1) {
		if (n & 1) n = 3 * n + 1;
		ans ++;
		n >>= 1;
	}
	cout << ans << endl;
	
	
	return 0;
}

1002 写出这个数 (20 分)

#include
using namespace std;

string s;
int ans;
vector <string> v;

string mp[10] = {"ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu"};

int main()
{
	cin >> s;
	for (int i = 0;i < s.size();i ++) 
		ans += s[i] - '0';
	while (ans) {
		v.push_back (mp[ans % 10]);
		ans /= 10;
	}
	
	cout << v[v.size()-1];
	for (int i = v.size()-2;i >= 0;i --)
	cout << ' ' << v[i];

	return 0;
}

1003 我要通过! (20 分)

题解链接

1004 成绩排名 (20 分)

#include
using namespace std;
const int INF = 0x3f3f3f3f;
int n, maxv, minv=INF, s;
string name, id;
map<int, pair <string, string> > stu;
int main()
{
	cin >> n;
	while (n --) {
		cin >> name >> id >> s;
		stu[s] = {name, id};
		minv = min (s, minv);
		maxv = max (s, maxv);
	}
	
	cout << stu[maxv].first << ' ' << stu[maxv].second << endl;
	cout << stu[minv].first << ' ' << stu[minv].second << endl;
	return 0;
}

1005 继续(3n+1)猜想 (25 分)

#include
using namespace std;
const int N = 5e6+10;

int n;
int st[N], a[N];
vector <int> ans;

void dfs (int x) {
	while (x != 1) {
		if (x&1) x = 3*x + 1;
		x >>= 1;
		st[x] = 1;
	}	
}

int main()
{
	cin >> n;
	for (int i = 1;i <= n;i ++) {
		cin >> a[i];
		if (!st[a[i]]) 
			dfs (a[i]);
	}
	
	sort (a+1, a+n+1); // 不一定保证输入序列是递增的 
	
	for (int i = n;i >= 1;i --)
		if (!st[a[i]])
			ans.push_back (a[i]);
	
	cout << ans[0];
	for (int i = 1;i < ans.size();i ++)
		cout << ' ' << ans[i];

	return 0;
}

1006 换个格式输出整数 (15 分)

#include
using namespace std;

int main()
{
	string s;
	
	cin >> s;
	
	if (s.size () == 3) {
		for (int i = 1;i <= s[0]-'0';i ++) cout << "B";
		s.erase (0, 1);
	}
	
	if (s.size () == 2) {
		for (int i = 1;i <= s[0]-'0';i ++) cout << "S";
		s.erase (0, 1);
	}
	
	for (int i = 1;i <= s[0]-'0';i ++) cout << i;

	return 0;
}

1007 素数对猜想 (20 分)

#include
using namespace std;

const int N = 1e5+10;

int n, cnt, prime[N], vis[N], ans;

int main()
{
	cin >> n;
	
	for (int i = 2;i <= n;i ++) {
		if (!vis[i]) prime[cnt++] = i;
		for (int j = 0;j < cnt;j ++) {
			if (i * prime[j] > n) break;
			vis[i * prime[j]] = 1;
			if (i % prime[j] == 0) break;
		}
	}
	
	for (int i = 2;i+2 <= n;i ++) 
		if (!vis[i] && vis[i+1] && !vis[i+2]) 
			ans ++;
			
	cout << ans << endl;
	
	return 0;
}

1008 数组元素循环右移问题 (20 分)

#include
using namespace std;
const int N = 500;
int n, m, a[N];
int main()
{
	cin >> n >> m;
	for (int i = 1;i <= n;i ++) cin >> a[i], a[i+n] = a[i];
	
	m %= n; // 不能少,如果m大于n时本质就是循环几轮之后又从某个位置开始 
	
	int flag = 0;
	for (int i = n-m+1;i <= 2*n-m;i ++) {
		if (flag) cout << ' ';
		cout << a[i];
		flag = 1;
	}
		
	return 0;
}

1009 说反话 (20 分)

#include
using namespace std;

string s;
stack <string> stk;

int main()
{
	getline (cin, s);
	
	int st = 0, ed = 0; // st 记录单词开头位置,ed 记录单词后面的空格或结束 
	while (ed != s.size ()) {
		ed = min (s.find (' ', ed+1), s.size ()); // 从ed+1(空格后第一个字符)开始找空格,如果找不到了min(s.size()),即取最后一个单词 
		string str = s.substr (st, ed-st); // 截取单词 
		stk.push (str); // 单词入栈 
		st = ed + 1; // 改变开头 
	}	

	while (stk.size () > 1) { // 出栈,逆序 
		cout << stk.top () << ' ';
		stk.pop ();
	}
	cout << stk.top ();
	
	return 0;
}

更新于2022.4.22
想到一个更简单的做法:

#include
using namespace std;
vector <string> v;

int main()
{
	string s, res;
	getline (cin, s);
	for (int i = 0;i < s.size();i ++) {
		if (s[i] == ' ') v.push_back (res), v.push_back (" "), res = "";
		else res += s[i];
	}
	v.push_back (res);
	
	for (int i = v.size()-1;i >= 0;i --) 
	cout << v[i];

	return 0;
}

1010 一元多项式求导 (25 分)

#include
using namespace std;

int a, n;
vector <pair <int, int> > ans;

int main()
{
	while (cin >> a >> n) { // ax^n
		if (n) ans.push_back ({a*n, n-1});
	}	
	if (ans.size() == 0) puts ("0 0");
	else {
		cout << ans[0].first << ' ' << ans[0].second;
		for (int i = 1;i < ans.size();i ++) 
			cout << ' ' << ans[i].first << ' ' << ans[i].second;
	}
	return 0;
}

1011 A+B 和 C (15 分)

#include
using namespace std;
typedef long long LL;
int main()
{
	int T;
	cin >> T;
	for (int i = 1;i <= T;i ++) {
		LL a, b, c;
		cin >> a >> b >> c;
		cout << "Case #" << i << ": " << (a + b > c ? "true" : "false") << endl;
	}	

	return 0;
}

1012 数字分类 (20 分)

#include
using namespace std;
int n, x, ans1, ans2, ans3, ans4, ans5, cnt, in;
int flag = 1;
int main()
{
	cin >> 	n;
	for (int i = 1;i <= n;i ++) {
		cin >> x;
		if (!(x&1) && !(x%5)) ans1 += x;
		if (x%5 == 1) ans2 += flag*x, flag = -flag, in = 1;
		if (x%5 == 2) ans3 ++;
		if (x%5 == 3) ans4 += x, cnt ++;
		if (x%5 == 4) ans5 = max (ans5, x);
	}
	
	if (!ans1) cout << "N";
	else cout << ans1;
	cout << ' ';
	
	if (!in) cout << "N";
	else cout << ans2;
	cout << ' ';
	
	if (!ans3) cout << "N";
	else cout << ans3;
	cout << ' ';
	
	if (!cnt) cout << "N";
	else printf ("%.1lf", 1.0*ans4/cnt);
	cout << ' ';
	
	if (!ans5) cout << "N";
	else cout << ans5;

	return 0;
}

1013 数素数 (20 分)

#include
using namespace std;
const int N = 5e6+10;

int n, m, cnt, prime[N], vis[N];

int main()
{
	cin >> m >> n;
	
	for (int i = 2;i < N;i ++) {
		if (!vis[i]) prime[++cnt] = i;
		if (cnt > n) break;
		for (int j = 1;j <= cnt;j ++) {
			if (i * prime[j] >= N) break;
			vis[i * prime[j]] = 1;
			if (i % prime[j] == 0) break;
		}
	}
	
	int flag = 0;
	for (int i = m;i <= n;i ++) {
		if ((i-m)%10 == 0) {
			if (flag) cout << endl;
			cout << prime[i];
			flag = 1;
		} else {
			cout << ' ' << prime[i];
		}
	}

	return 0;
}

1014 福尔摩斯的约会 (20 分)

测试点太坑了!

测试点分析

#include
using namespace std;

string s1, s2;
vector <char> v;
string day[10] = {"MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"};

int main()
{
	cin >> s1 >> s2;
	int len = min (s1.size(), s2.size());
	int flag = 0;
	char d, h;
	for (int i = 0;i < len;i ++) {
		if (!flag) {
			if (s1[i] >= 'A' && s1[i] <= 'G'&& s1[i] == s2[i]) 
				d = s1[i], flag = 1;
		} else {
			if (s1[i] == s2[i] && (isdigit (s1[i]) || (s1[i] >= 'A' && s1[i] <= 'N'))) {
				h = s1[i];
				break;
			}
		}
	}
	
	cout << day[d - 'A'] << ' ';
	if (isdigit (h)) cout << "0" << h;
	else cout << 10 + (h - 'A');
	cout << ":";
	
	cin >> s1 >> s2;
	int pos;
	len = min (s1.size(), s2.size());
	for (int i = 0;i < len;i ++) {
		if (isalpha (s1[i]) && s1[i] == s2[i]) {
			pos = i;
			break;
		}
	}
	printf ("%02d\n", pos);

	return 0;
}

1015 德才论 (25 分)

#include
using namespace std;

struct student {
	string id;
	int de;
	int cai;
};

vector <student> level[5];

bool cmp (student a, student b) {
	if (a.de + a.cai != b.de + b.cai) return a.de + a.cai > b.de + b.cai;
	if (a.de != b.de) return a.de > b.de;
	return a.id < b.id;
}

int main()
{
	int n, L, H, ans = 0;
	cin >> n >> L >> H;
	
	for (int i = 1;i <= n;i ++) {
		string id;
		int de, cai, lv;
		cin >> id >> de >> cai;
		if (de < L || cai < L) continue;
		if (de >= H && cai >= H) lv = 1;
		else if (de >= H && cai < H) lv = 2;
		else if (de < H && cai < H && de >= cai) lv = 3;
		else lv = 4;
		
		level[lv].push_back ({id, de, cai});
	}	
	
	for (int i = 1;i <= 4;i ++) {
		ans += level[i].size();
		sort (level[i].begin(), level[i].end(), cmp);
	}
	
	cout << ans << endl;
	for (int i = 1;i <= 4;i ++)
		for (int j = 0;j < level[i].size();j ++)
			cout << level[i][j].id << ' ' << level[i][j].de << ' ' << level[i][j].cai << endl;
	
	return 0;
}

1016 部分A+B (15 分)

#include
using namespace std;

int main()
{
	int a, x, b, y;
	int r1 = 0, r2 = 0;
	cin >> a >> x >> b >> y;
	while (a) {
		if (a%10 == x) r1 = r1*10 + x;
		a/=10;
	}	

	while (b) {
		if (b%10 == y) r2 = r2*10 + y;
		b/=10;
	}
	
	cout << r1 + r2 << endl;
	return 0;
}

1017 A除以B (20 分)

高精度模板

#include
using namespace std;

string a;
int b, r;
vector <int> Q;

int main()
{
	cin >> a >> b;
	
	for (int i = 0;i < a.size();i ++) {
		r = r * 10 + (a[i] - '0');
		int cnt = 0;
		while (r >= b) {
			r -= b;
			cnt ++;
		}
		Q.push_back (cnt);
	} 
	int i = 0; 
	while (i < Q.size()-1 && Q[i] == 0) i ++;
	for (;i < Q.size();i ++) cout << Q[i];
	cout << ' ' << r << endl; 	

	return 0;
}

1018 锤子剪刀布 (20 分)

#include
using namespace std;
int cnt[2][3]; // cnt[0][0]:jia-B   cnt[0][1]:jia-C   cnt[0][2]:jia-J
int check (char x, char y) { // 0:ping 1:jiawin 2:yiwin
	if (x == y) return 0;
	if (x == 'J' && y == 'B' || x == 'B' && y == 'C' || x == 'C' && y == 'J') return 1;
	else return 2;
}

map <char, int> mp = {{'B', 0}, {'C', 1}, {'J', 2}};
string remp = "BCJ";
int main()
{
	int n;
	char a, b;
	int awin = 0, bwin = 0, ping = 0, amx = 0, bmx = 0;
	cin >> n;
	while (n --) {
		cin >> a >> b;
		int res = check (a, b);
		if (res == 1) awin ++, cnt[0][mp[a]] ++, amx = max (amx, cnt[0][mp[a]]);
		else if (res == 2) bwin ++, cnt[1][mp[b]] ++, bmx = max (bmx, cnt[1][mp[b]]);
		else ping ++;
	}
	
	cout << awin << ' ' << ping << ' ' << bwin << endl;
	cout << bwin << ' ' << ping << ' ' << awin << endl;
	for (int i = 0;i < 3;i ++)
	if (cnt[0][i] == amx) {
		cout << remp[i] << ' ';
		break;
	}
	for (int i = 0;i < 3;i ++) 
	if (cnt[1][i] == bmx) {
		cout << remp[i];
		break;
	}

	return 0;
}

1019 数字黑洞 (20 分)

#include
using namespace std;
string s, ss;
int x, y, z;
int main()
{
	cin >> s;
	while (z != 6174) {
		while (s.size() < 4) s = "0" + s; // 补0操作不能少 
		sort (s.begin(), s.end());
		x = y = 0;
		for (int i = 0;i < s.size();i ++) {
			x = x * 10 + (s[s.size() - i - 1] - '0');
			y = y * 10 + (s[i] - '0');
		}
		if (x == y) return printf ("%04d - %04d = 0000", x, y), 0;
		z = x - y;
		printf ("%04d - %04d = %04d\n", x, y, z);
		s = to_string(z);
	}	
	
	return 0;
}

1020 月饼 (25 分)

#include
using namespace std;

double ans = 0;

struct node {
	double x, y;
} a[1100];

bool cmp (node a, node b) {
	return a.y / a.x > b.y / b.x;
}

int main()
{
	double D;
	int n;
	cin >> n >> D;
	for (int i = 0;i < n;i ++) cin >> a[i].x;
	for (int i = 0;i < n;i ++) cin >> a[i].y;
	sort (a, a + n, cmp);
	for (int i = 0;i < n;i ++) {
		if (D <= 0) break;
		if (D >= a[i].x) D -= a[i].x, ans += a[i].y;
		else ans += 1.0 * D * a[i].y / a[i].x, D = 0;
	}	
	printf ("%.2lf\n", ans);
	return 0;
}

1021 个位数统计 (15 分)

#include
using namespace std;
const int N = 1e5+10;
set <int> st;
string s;
int cnt[N];

int main()
{
	cin >> s;
	for (int i = 0;i < s.size();i ++)
	cnt[s[i]-'0'] ++, st.insert (s[i]-'0');
	for (int i : st) printf ("%d:%d\n", i, cnt[i]);

	return 0;
}

1022 D进制的A+B (20 分)

#include
using namespace std;

int a, b, k, base, r1, r2;
int main()
{
	cin >> a >> b >> k;
	base = 1;
	while (a) {
		r1 += (a % 10) * base; 
		a/=10;
		base *= 10;
	}
	base = 1;
	while (b) {
		r2 += (b % 10) * base;
		b/=10;
		base *= 10;
	}
	int res = r1 + r2;
	string ans = "";
	base = 1;
	while (res) {
		ans = to_string(res % k) + ans;
		res /= k;
	}
	if (ans == "") cout << 0 << endl; // 一个测试点 
	else cout << ans << endl;
	return 0;
}

更新于2022.4.22

更简单的写法:

#include
using namespace std;
typedef long long LL;
LL a, b, k;
vector <LL> v;
int main()
{
	cin >> a >> b >> k;
	LL c = a + b;
	while (c) { // 当c=0时无法进入循环,所以v.size()==0 
		v.push_back (c % k);
		c /= k;
	}	
	if (v.size() == 0) return cout << 0 << endl, 0; // 一个测试点 
	for (int i = v.size()-1;i >= 0;i --) cout << v[i];

	return 0;
}

1023 组个最小数 (20 分)

#include
using namespace std;
const int N = 20;

int cnt[N];

int main()
{
	for (int i = 0;i < 10;i ++)	
	cin >> cnt[i];
	
	for (int i = 1;i < 10;i ++)
	if (cnt[i]) {
		cnt[i] --, cout << i;
		break;
	}
	
	for (int i = 0;i < 10;i ++) 
		for (int j = 0;j < cnt[i];j ++) 
			cout << i;
	
	return 0;
}

1024 科学计数法 (20 分)

分指数小于0和大于等于0两种情况,对于大于等于0的情况还要再细分是否输出.

#include
#include
using namespace std;
int main()
{
    string s;
    cin >> s;
    int pos_E = s.find ('E');
    int pos_dot = s.find ('.');

    int exp = atoi(s.substr (pos_E+1).c_str());
    string flag = (s[0] == '-'?"-":"");
    string dec = s.substr (0, pos_E);
    dec.erase (dec.begin() + pos_dot);
    dec.erase (dec.begin());

    cout << flag;
    if (exp >= 0) {
        int t = exp - (pos_E - pos_dot - 1);
        if (t >= 0) {
            cout << dec;
            for (int i = 0;i < t;i ++) cout << '0';
        } else {
            for (int i = 0;i < dec.size();i ++) {
                cout << dec[i];
                if (i == exp) cout << '.';
            }
        }
    } else {
        int t = 0;
        for (int i = 0;i < abs (exp);i ++) {
            cout << "0";
            if (!t) cout << '.';
            t = 1;
        }
        cout << dec;
    } 
    return 0;
}

1025 反转链表 (25 分)

沃日,柳神太强了吧!!!

#include
using namespace std;
const int N = 1e6+10;
int lst[N], dta[N], nxt[N];
int main()
{
	int st, n, k;
	cin >> st >> n >> k;
	while (n --) {
		int add, val, ne;
		cin >> add >> val >> ne;
		dta[add] = val, nxt[add] = ne;
	}
	
	int p = st, cnt = 0;
	while (p != -1) {
		lst[cnt ++] = p;
		p = nxt[p];
	}
	
	for (int i = 0;i < (cnt - cnt % k);i += k)
		reverse (lst + i, lst + i + k);
	
	for (int i = 0;i < cnt - 1;i ++)
		printf ("%05d %d %05d\n", lst[i], dta[lst[i]], lst[i + 1]);
	printf ("%05d %d -1\n", lst[cnt-1], dta[lst[cnt-1]]);

	return 0;
}

1026 程序运行时间 (15 分)

#include
using namespace std;

int main()
{
	int a,b;
	cin >> a >> b;
	int c = b - a;
	int d = int (1.0 * c / 100 + 0.5);
	
	int h = d / 3600;
	int m = d / 60 % 60;
	int s = d % 60;
	
	printf ("%02d:%02d:%02d\n", h, m, s);

	return 0;
}

1027 打印沙漏 (20 分)

#include 
using namespace std;

int main()
{
    int n;
    char ch;
    scanf("%d %c", &n, &ch);
    // target 表示本次需要使用的符号数
    int target = 1, col = 3, row = 1;
    while ((target + col * 2) <= n) {
        target += col * 2;
        col += 2;
        row++;
    }
    col -= 2;
    // 打印上半部分
    for (int i = 0; i < row; i++) {
        for (int j = 0; j < col - i; j++) {
            if (j < i) {
                putchar(' ');
            } else {
                putchar(ch);
            }
        }
        putchar('\n');
    }
    // 打印下半部分
    for (int i = row - 2; i >= 0; i--) {
        for (int j = 0; j < col - i; j++) {
            if (j < i) {
                putchar(' ');
            } else {
                putchar(ch);
            }
        }
        putchar('\n');
    }
    printf("%d", n - target);
    return 0;
}

1028 人口普查 (20 分)

注意,要比较年龄大小不是只比较年份,需要比较出生了多少天。

而且计算天数的时候不能从出生日期枚举到今天,会超时。

#include
using namespace std;

int n, y, m, d, min_day = 1000000, max_day = -1, ans;
string name, max_ans, min_ans;

bool isrun (int y) {
	if ((y % 4 == 0 && y % 100 != 0) || y % 400 == 0) return true;
	return false;
}

int add (int y, int m, int flag) {
	if (m == 2) {
		if (isrun (y)) return flag * 29;
		else return flag * 28;
	} else if (m == 1 || m == 3 || m == 5 || m ==7 || m == 8 || m == 10 || m == 12) 
		return flag * 31;
	else 
		return flag * 30;
}

int getday (int y, int m, int d) { // -1表示不合法,其他表示出生至今的天数 
	int res = 0;
	
	// 如果还未出生,今日出生合法 
	if (y > 2014) return -1;
	if (y == 2014 && m > 9) return -1;
	if (y == 2014 && m == 9 && d > 6) return -1;
	
	// 判断是否超200岁,注意超如果年份相减为200,还需要比较生日与今天的早晚,如果过了200岁生日相当于201,但2014-y还是200! 
	int age = 2014 - y;
	if (m < 9) age ++;
	else if (m == 9) {
		if (d < 6) age ++;
	}
	if (age > 200) return -1;
	
	// 大致思路是计算y到2013年的全部天数,减去从y年的1月1号到m月d号的日子,再加上2014年1月1号到今天的日子 
	for (int i = y;i < 2014;i ++)
	if (isrun (i)) res += 366;
	else res += 365;

	for (int i = 1;i < m;i ++)
		res += add (y, i, -1);
	res -= d;
	
	for (int i = 1;i < 9;i ++) 
		res += add (y, i, 1);
	res += 6;
	
	return res;
}

int main()
{
	cin >> n;
	while (n --) {
		cin >> name;
		scanf ("%d/%d/%d", &y, &m, &d);
		
		int day = getday (y, m, d);
		if (day == -1) continue;
		if (day < min_day) {
			min_day = day;
			min_ans = name;
		}
		if (day > max_day) {
			max_day = day;
			max_ans = name;
		}
		ans ++;
	}	
		
	if (ans == 0) puts ("0");
	else cout << ans << ' ' << max_ans << ' ' << min_ans << endl;
	return 0;
}

1029 旧键盘 (20 分)

千万不要把这个题理解成什么字符串匹配之类的问题,这就是个看第二行的字符串比第一行的字符串少了哪些种类的字符,而且要将字符串都转换为大写或小写来比较,最好是转换成大写因为最后让输出大写,否则还要再转换一次。

#include
using namespace std;

string s1, s2;
set <char> set1, set2;
vector <char> v1, v2;
int main()
{
	cin >> s1 >> s2;
	transform (s1.begin (), s1.end (), s1.begin (), ::toupper);
	transform (s2.begin (), s2.end (), s2.begin (), ::toupper);

	for (int i = 0;i < s1.size();i ++) {
		if (set1.find (s1[i]) == set1.end ())
			v1.push_back (s1[i]),
			set1.insert (s1[i]);
	}
	
	for (int i = 0;i < s2.size();i ++) {
		if (set2.find (s2[i]) == set2.end ())
			v2.push_back (s2[i]), 
			set2.insert (s2[i]);
	}
	
	for (int i = 0, j = 0;i < v1.size();i ++) 
		if (v2[j] != v1[i]) cout << v1[i];
		else j ++;
		
	return 0;
}

1030 完美数列 (25 分)

题解链接

1031 查验身份证 (15 分)

#include
using namespace std;

string mp = "10X98765432";
int w[17] = {7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
string sfz;
int n;
vector <string> ans;

int main()
{
	cin >> n;
	while (n --) {
		cin >> sfz;
		int sum = 0;
		for (int i = 0;i < 17;i ++)
			sum += (sfz[i] - '0') * w[i];
		if (sfz[17] != mp[sum % 11])
			ans.push_back (sfz);
	}
	if (ans.size()) {
		for (int i = 0;i < ans.size();i ++)
			cout << ans[i] << endl;
	} else {
		puts ("All passed");
	}
	return 0;
}

1032 挖掘机技术哪家强 (20 分)

#include
using namespace std;

int n, s, mx=-1; // -测试点 
string cla, ans;
map <string, int> cnt;
int main()
{
	cin >> n;
	while (n --) {
		cin >> cla >> s;
		cnt[cla] += s;
		if (cnt[cla] > mx) {
			mx = cnt[cla];
			ans = cla;
		}
	}	
	cout << ans << ' ' << mx << endl;

	return 0;
}

1033 旧键盘打字 (20 分)

注意:

  1. 要使用 getline !
  2. +是上档键,其他符号均不是!
#include
#define NONE string::npos
using namespace std;
string err, s;
int main()
{
	getline (cin, err);
	getline (cin, s);
	
	for (int i = 0;i < s.size();i ++) {
		if (err.find ('+') != NONE && s[i] >= 'A' && s[i] <= 'Z') continue;

		if (err.find (toupper (s[i])) != NONE) continue;
		
		cout << s[i];
	}	
	
	cout << endl;

	return 0;
}

1034 有理数四则运算 (20 分)

这种给出分子和分母进行四则运算的题,想要计算结果不要一上来就对输入的四个数进行约分化简啥的,因为没意义,完全可以直接通过四个数的简单运算得到结果的分子和分母。

本题无论是结果部分,还是操作数部分,都具有相同的输出格式,所以我们采用同一函数处理。

#include
using namespace std;
typedef long long LL; 
void func (LL a, LL b) {
	if (a * b == 0) { // a==0 || b==0
		if (b == 0) cout << "Inf";
		else cout << '0';
		return ;
	}
	
	int flag = 0;
	if ((a < 0 && b > 0) || (a > 0 && b < 0)) flag = 1; // 记录符号 
	a = abs (a), b = abs (b);
	
	if (flag) cout << "(-"; // 输出左括号和符号,与下面的flag语句呼应 
	
	if (a / b != 0) { // 存在整数部分k 
		cout << a / b; // 输出整数部分 
		if (a % b != 0) cout << ' '; // 存在分数部分,则先输出空格 
		a -= a / b * b; // 分子比分母小 
	} 
	if (a != 0) { // 分子不是0才输出分数部分 
		int gcd = __gcd (a, b);
		a /= gcd, b /= gcd; // 约分 
		printf ("%lld/%lld", a, b);
	}
	
	if (flag) cout << ')';
}

int main()
{
	LL a, b, c, d;
	scanf ("%lld/%lld %lld/%lld", &a, &b, &c, &d);
	
	func (a, b); printf (" + "); func (c, d); printf (" = "); func (a*d+b*c, b*d); 	puts ("");
	func (a, b); printf (" - "); func (c, d); printf (" = "); func (a*d-b*c, b*d); 	puts ("");
	func (a, b); printf (" * "); func (c, d); printf (" = "); func (a*c, b*d); 		puts ("");
	func (a, b); printf (" / "); func (c, d); printf (" = "); func (a*d, b*c); 

	return 0;
}

1035 插入与归并 (25 分)

感觉这个题出的挺拉的。

有些情况既可以归为插入也可以归为归并;数据过于水,各种得到归并排序的合并区间的大小的方法都能过。

下面注释掉的方法是,取前两个不降序序列的长度中的较小者作为得到第二个序列时采用的合并区间的大小;没注释掉的方法是统计全部非最后一个不降序序列的长度的最小值作为得到第二个序列时采用的合并区间,之所以采用这个思路是因为前一个思路对于如下输入是不正确的(尽管可以过):

13
2 1 6 5 8 7 4 3 10 12 9 13 11
1 2 5 6 7 8 3 4 10 12 9 13 11

1 2 5 6 3 4 7 8 9 10 12 13 11

可以看出得到第二个序列采用的合并区间大小为2,即从第一个变为第二个是将相邻大小为1进行合并得到的,即每两个相邻的元素是有序的;所以下一步应该是保证每四个相邻元素是有序的;
但是要采用前一个思路,则会得到第二个序列采用的合并区间大小为4,下一步会将整个序列排列有序。


太坑了,判断是否为插入排序的时候不严格也可以。

#include
using namespace std;
int a[110], b[110], n;
int main()
{
	cin >> n;
	for (int i = 1;i <= n;i ++) cin >> a[i];
	for (int i = 1;i <= n;i ++) cin >> b[i];
	
	int k = 2, pos = 2;
	while (k <= n && b[k] >= b[k-1]) k ++, pos = k; // >= 一个测试点
	while (k <= n && b[k] == a[k]) k ++;
	pos = min (pos, n);
	if (k > n) { // insert
		puts ("Insertion Sort");
		sort (b + 1, b + pos + 1);
	} else { // merge
		puts ("Merge Sort");
		int len1 = 1, len2 = 1, flag = 0;
//		for (int i = 1;i < n;i ++) {
//			if (!flag) {
//				if (b[i+1] >= b[i]) len1 ++;
//				else flag = 1;
//			} else {
//				if (b[i+1] >= b[i]) len2 ++;
//				else break;
//			}
//		}
		int len = 1, min_len = n;
		for (int i = 2;i <= n;i ++) {
			if (b[i] > b[i-1]) len ++;
			else min_len = min (len, min_len), len = 1;
		}
		int i;
		int span = min_len;
//		int span = min (len1, len2);
		if (2 * span >= n) sort (b+1, b+n+1);
		else {
			for (i = 2*span + 1;i <= n;i += 2*span) 
				sort (b + i - 2 * span, b + i);
			sort (b + i - 2 * span, b + n + 1);
		}
		
	}
	for (int i = 1;i < n;i ++) cout << b[i] << ' ';
	cout << b[n];

	return 0;
}

1036 跟奥巴马一起编程 (15 分)

#include
using namespace std;

int main()
{
	int n;
	char c;
	cin >> n >> c;

	for (int i = 1;i <= n;i ++) cout << c;
	cout << endl;
		
	for (int i = 2;i < (n+1)/2;i ++) {
		cout << c;
		for (int j = 1;j < n-1;j ++)
		cout << ' ';
		cout << c << endl;
	}
	
	for (int i = 1;i <= n;i ++) cout << c;
	cout << endl;
	return 0;
}

1037 在霍格沃茨找零钱 (20 分)

#include
using namespace std;
typedef long long LL;
LL a, b, c, x, y, z;
int main()
{
	scanf ("%lld.%lld.%lld %lld.%lld.%lld", &a, &b, &c, &x, &y, &z);
	
	LL alpha = ( a * 17 + b ) * 29 + c;
	LL beta = (x * 17 + y) * 29 + z;
	LL diff = beta - alpha;
	
	if (diff < 0LL) cout << '-', diff = abs (diff);
	
	printf ("%lld.%lld.%lld\n", diff / 29 / 17, diff / 29 % 17, diff % 29);

	return 0;
}

1038 统计同成绩学生 (20 分)

#include
using namespace std;
const int N = 1e5+10;
int n, x, cnt[N];

int main()
{
	cin >> n;
	for (int i = 1;i <= n;i ++) cin >> x, cnt[x] ++;
	cin >> n;
	for (int i = 1;i < n;i ++) cin >> x, cout << cnt[x] <<' ';
	cin >> x;
	cout << cnt[x] << endl;

	return 0;
}

1039 到底买不买 (20 分)

#include
using namespace std;
int cnt[1100], ans;
int main()
{
	string s, h;
	cin >> s >> h;
	
	for (int i = 0;i < s.size();i ++)
	cnt[s[i]] ++;
	
	for (int i = 0;i < h.size();i ++) {
		cnt[h[i]] --;
		if (cnt[h[i]] < 0) ans ++;
	}
	
	if (ans) cout << "No " << ans << endl;
	else cout << "Yes " << s.size () - h.size() << endl;
	

	return 0;
}

1040 有几个PAT (25 分)

题解链接

1041 考试座位号 (15 分)

#include
#define PSI pair <string, int>
using namespace std;
const int N = 1e4;
PSI ans[N];
int n, a, b;
string s;

int main()
{
	cin >> n;
	for (int i = 1;i <= n;i ++) {
		cin >> s >> a >> b;
		ans[a] = {s, b};
	}	

	cin >> n;
	while (n--) {
		cin >> a;
		cout << ans[a].first << ' ' << ans[a].second << endl;
	}
	
	
	return 0;
}

1042 字符统计 (20 分)

#include
using namespace std;

string s;
int cnt[1000], mx = 0;
int main()
{
	getline (cin, s);
	
	transform (s.begin(), s.end(), s.begin(), ::tolower);
	
	for (int i = 0;i < s.size();i ++)
	if (isalpha(s[i])) cnt[s[i]] ++, mx = max (mx, cnt[s[i]]);
		
	for (int i = 'a';i <= 'z';i ++)
	if (cnt[i] == mx) return cout << char(i) << ' ' << cnt[i] << endl, 0;

	return 0;
}

1043 输出PATest (20 分)

#include
using namespace std;
const int N = 500;
string s, mp = "PATest";
int cnt[N];
int main()
{
	getline (cin, s);
	for (int i = 0;i < s.size();i ++) cnt[s[i]] ++;
	
	while (1) {
		int flag = 0;
		
		for (int i = 0;i < 6;i ++) {
			if (cnt[mp[i]]) cnt[mp[i]] --, cout << mp[i];
			flag |= cnt[mp[i]]; // 全0,则flag=0 
		}
		
		if (!flag) break;
	}

	return 0;
}

1044 火星数字 (20 分)

本题注意只有一种情况会输出tret,就是输入为0;tret总是单独一个字符串存在的。

#include 
using namespace std;
using namespace std;
string a[13] = {"tret", "jan", "feb", "mar", "apr", "may", "jun", "jly", "aug", "sep", "oct", "nov", "dec"};
string b[13] = {"?", "tam", "hel", "maa", "huh", "tou", "kes", "hei", "elo", "syy", "lok", "mer", "jou"};
string s;

int main () {
    int T;
    cin >> T;
    getchar ();
    while (T --) {
        getline (cin, s);
        if (isdigit (s[0])) { // number
            int x = atoi (s.c_str());
            int p = x / 13, q = x % 13;
            if (p && q) cout << b[p] << ' ' << a[q] << endl;
            if (p && !q) cout << b[p] << endl;
            if (!p) cout << a[q] << endl;
        } else {
            string lp = s.substr (0, 3);
            int n = s.size();
            string rp = s.substr (min (4, n));
            int r1 = 0, r2 = 0;
            for (int i = 0;i < 13;i ++) {
                if (a[i] == lp || a[i] == rp) r2 = i;
                if (b[i] == lp) r1 = i;
            }
            cout << r1 * 13 + r2 << endl;
        }
    }
}

1045 快速排序 (25 分)

看正确率以为很难,其实不难,就是有点坑,测试点2要求0个的时候第二行要输出空行。

稍微用点思维吧,顺序遍历的时候更新遇到的最大值,逆序遍历的时候更新遇到的最小值,如果遇到的

#include
using namespace std;

const int N = 1e6+10;
int n, a[N];
map <int, bool> st;
vector <int> v;

int main()
{
    cin >> n;
    for (int i = 0;i < n;i ++) cin >> a[i];
    
    int mx = -1;
    for (int i = 0;i < n;i ++) {
        if (a[i] > mx) st[a[i]] = true;
        mx = max (mx, a[i]);
    }
    
    int mn = 1e9+10;
    for (int i = n-1;i >= 0;i --) {
        if (a[i] > mn) st[a[i]] = false;
        mn = min (mn, a[i]);
        if (st[a[i]]) v.push_back (a[i]);
    }

    cout << v.size() << endl;
    if (v.size()) {
        sort (v.begin (), v.end ());
        cout << v[0];
        for (int i = 1;i < v.size();i ++) cout << ' ' << v[i];
    } else {
        cout << endl; //一个测试点
    }
    
    return 0;
}

1046 划拳 (15 分)

#include 
using namespace std;

int am, ah, bm, bh, ad, bd, T;

int main () {
    cin >> T;
    while (T --) {
        cin >> am >> ah >> bm >> bh;
        if ((am + bm == ah) ^ (am + bm == bh)) {
            if (am + bm == ah) bd ++;
            else ad ++;
        }
    }
    cout << ad << ' ' << bd << endl;
}

1047 编程团体赛 (20 分)

#include
using namespace std;
int cnt[11000], s, num, id, mx=-1, st[11000];
int main()
{
	int n;
	cin >> n;
	while (n --) {
		scanf ("%d-%d %d", &id, &num, &s);
		cnt[id] += s, mx = max (mx, cnt[id]), st[id] = 1;	
	}
	
	
	for (int i = 1;i <= 1000;i ++)	
	if (st[i] && cnt[i] == mx) 
	return cout << i << ' ' << mx << endl, 0;

	return 0;
}

1048 数字加密 (20 分)

#include
using namespace std;
string A, B, ans;
string mp = "0123456789JQK";
int main()
{
	cin >> A >> B;
	int nA = A.size(), nB = B.size();
	int n = max (nA, nB);
	for (int i = 0;i < n - nA;i ++) A = "0" + A;
	for (int i = 0;i < n - nB;i ++) B = "0" + B;
	
	reverse (A.begin(), A.end());
	reverse (B.begin(), B.end());
	
	for (int i = 0;i < n;i ++) {
		char ch;
		if (i & 1) ch = (B[i] - A[i] + 10) % 10 + 48;
		else ch = mp[(A[i] - '0' + B[i] - '0') % 13];
		ans = ch + ans;
	}
	cout << ans << endl;
	
	return 0;
}

1049 数列的片段和 (20 分)

柳神用的扩大一定的倍数来保证精度不丢失,我是直接使用了long double,注意longdouble在使用printf输出时要用Lf!

(一开始还想直接算组合数,仔细一看范围就不行了,所以换了思路)

#include
using namespace std;
const int N = 1e5+10;
int n;
long double ans, sum, d[N];
int main()
{
	cin >> n;
	for (int i = n;i >= 1;i --) {
		cin >> d[i];
		cout << d[i] << endl;
		sum += d[i] * i;
	}	
	for (int i = n;i >= 1;i --) {
		ans += sum;
		sum -= d[i] * i;
	}
	printf ("%.2Lf\n", ans);

	return 0;
}

更新于2022.4.22
看不懂自己之前写的代码了,重新写了个简单的:

#include
using namespace std;
int n;
long double x, ans;
int main()
{
	cin >> n;
	for (int i = 1;i <= n;i ++) {
		scanf ("%Lf", &x);
		ans += x * i * (n-i+1);
	}	
	printf ("%.2Lf", ans);
	return 0;
}

1050 螺旋矩阵 (25 分)

首先说明一下题目的意思,就是需要自己去确定m和n,m和n满足:

  1. m * n = N;
  2. m不小于n;
  3. 二者的差值尽可能小.

先按照题目说的顺序赋值到一个新的数组中,再输出。

由于如果直接开数组会爆,所以需要开二维vector,行是m列是n。(如果会用C里的分配空间的函数也可以,我忘记如何用了)

#include
using namespace std;
int M, n, m;
int main()
{
	cin >> M;
	m = (int) sqrt (M);
	while (m <= M && !(M % m == 0 && m >= M / m)) m ++; // 只要m大于M,不停的m++,直到m整除M且m比n大 
	n = M / m;
	
	vector <int> a (M);
	for (int i = 0;i < M;i ++) scanf ("%d", &a[i]);
	
	sort (a.begin (), a.end ()); // 从小到大排序即可, 倒序赋值 
	
	vector <vector <int> > b (m, vector <int> (n)); // 初始化!!记住如何初始化 
	int l = 0, r = n-1, u = 0, d = m-1;
	
	while (1) {
		for (int i = l;i <= r;i ++) b[u][i] = a[-- M];
		u ++;
		if (M == 0) break; // 每一个break都不可以缺少 
		for (int i = u;i <= d;i ++) b[i][r] = a[-- M];
		r --;
		if (M == 0) break;
		for (int i = r;i >= l;i -- ) b[d][i] = a[-- M];
		d --;
		if (M == 0) break;
		for (int i = d;i >= u;i --) b[i][l] = a[-- M];
		l ++;
		if (M == 0) break;
	}
	
	for (int i = 0;i < m;i ++, cout << endl) {
		int flag = 0;
		for (int j = 0;j < n;j ++) {
			if (flag) printf (" ");
			flag = 1;
			printf ("%d", b[i][j]);
		}
	}
	
	return 0;
}

1051 复数乘法 (15 分)

无需控制实部为零不输出实部,虚部为零不输出虚部,没有这个测试点。

只需要注意精度小于一定程度的时候归为0,例如0.003-0.004i是要输出0.00+0.00i的,如果不归零则会出现输出-0.00i的情况。

#include
using namespace std;
const double eps = 0.0001;
double r1,r2,p1,p2,a1,a2,b1,b2,a,b;
int main()
{
	cin >> r1 >> p1 >> r2 >> p2;
	
	a1 = r1 * cos (p1);
	b1 = r1 * sin (p1);
	
	a2 = r2 * cos (p2);
	b2 = r2 * sin (p2);
	
//	(a1 + b1 * i) * (a2 + b2 * i)
//	=> (a1*a2 - b1*b2) + (a1*b2 + a2*b1) * i

	a = a1*a2 - b1*b2;
	b = a1*b2 + a2*b1;
	
	if (fabs (a) < eps) a = 0; // 两个测试点 
	if (fabs (b) < eps) b = 0; // 两个测试点 
	
	printf ("%.2lf%+.2lfi", a, b); 
	return 0;
}

1052 卖个萌 (20 分)

我眼瞎,没看见要输出括号,debug良久。

#include
using namespace std;

string s;
vector <string> op[5];
int cnt[1010], a[1010];

int main()
{
	for (int k = 1;k <= 3;k ++) {
		getline (cin, s);
		for (int i = 0;i < s.size();i ++) 
			if (s[i] == '[') 
				op[k].push_back (s.substr (i+1, s.find (']', i) - i - 1));
				
//		cout << op[k][0].size() << endl;
	}
	int T;
	cin >> T;
	while (T --) {
		int flag = 0;
		for (int i = 0;i < 5;i ++) {
			cin >> a[i];
			int j = abs (2 - abs (2 - i)) + 1;
			if (a[i] > op[j].size() || a[i] < 1) {
				flag = 1;
				break;
			}
		}
		if (flag) puts ("Are you kidding me? @\\/@");
		else {
			for (int i = 0;i < 5;i ++) {
				int j = abs (2 - abs (2-i)) + 1;
				if (i == 1) cout << '(';
				if (i == 4) cout << ')';
				cout << op[j][a[i]-1];
			}
			cout << endl;
		}
	}
	
	return 0;
}

1053 住房空置率 (20 分)

如果是“空置”,那么就不是“可能空置”了。

#include
using namespace std;
int n, D, k, ans1, ans2, cnt;
double e, x;
int main()
{
	cin >> n >> e >> D;
	for (int i = 1;i <= n;i ++, cnt = 0) {
		cin >> k;
		for (int j = 1;j <= k;j ++) {
			cin >> x;
			if (x < e) cnt ++;
		}
		if (cnt > 0.5 * k) {
			ans1 ++;
			if (k > D) ans2 ++;
		}
	}	
	
	printf ("%.1lf%% %.1lf%%", 100.0 * (ans1 - ans2) / n, 100.0 * ans2 / n);

	return 0;
}

1054 求平均值 (20 分)

看的柳神的!

有关 sscanf 和 sprintf 的用法

#include
using namespace std;
char s[100], ss[100];
int main()
{
	int n, cnt = 0;
	double sum = 0;
	double tmp = 0;
	cin >> n;
	while (n--) {
		scanf ("%s", s);
		sscanf (s, "%lf", &tmp);
		sprintf (ss, "%.2lf", tmp);
		
		int flag = 0;
		for (int i = 0;i < strlen (s);i ++)
		if (s[i] != ss[i]) flag = 1;
		if (flag || tmp < -1000 || tmp > 1000) {
			printf ("ERROR: %s is not a legal number\n", s);
			continue;
		}
		cnt ++;
		sum += tmp;
	}	

	if (!cnt) printf ("The average of 0 numbers is Undefined");
	else if (cnt == 1) printf ("The average of 1 number is %.2lf", sum);
	else printf ("The average of %d numbers is %.2lf", cnt, sum/cnt);
	return 0;
}

1055 集体照 (25 分)

题解链接

1056 组合数的和 (15 分)

请多一点这种题!

这数据量、空限、时限都非常感人~ ~ ~ ~

#include
using namespace std;

int n, a[100], ans;

int main()
{
	cin >> n;
	for (int i = 0;i < n;i ++) cin >> a[i];
	for (int i = 0;i < n;i ++)
	for (int j = 0;j < n;j ++)
	if (i != j) ans += a[i] * 10 + a[j];
	
	cout << ans << endl;	

	return 0;
}

1057 数零壹 (20 分)

#include
using namespace std;
string s;
int n, cnt0, cnt1;
int main()
{
	getline (cin, s);
	transform (s.begin(), s.end(), s.begin(), ::tolower);
	for (int i = 0;i < s.size();i ++)
	if (isalpha (s[i])) n += (s[i] - 96);
	
	while (n) {
		if (n & 1) cnt1 ++;
		else cnt0 ++;
		n >>= 1;
	}
	cout << cnt0 << ' ' << cnt1 << endl;

	return 0;
}

1058 选择题 (20 分)

#include
using namespace std;
const int N = 1e5+10;
int n, m, score[N], num[N], rn;
int mx_wrong, wrong[N];
int st[N][10], stuop[10];
char op;
int main()
{
	cin >> n >> m;
	for (int i = 1;i <= m;i ++)	{
		cin >> score[i] >> num[i] >> rn;
		for (int j = 1;j <= rn;j ++) {
			cin >> op;
			st[i][op-96] = 1;
		}
	}
	getchar ();
	while (n --) {
		int sum = 0;
		for (int i = 1;i <= m;i ++) {
			memset (stuop, 0, sizeof stuop);
			int k, flag = 0;
			getchar ();
			cin >> k;
			for (int j = 1;j <= k;j ++) {
				cin >> op;
				stuop[op-96] = 1;
			}
			for (int j = 1;j <= num[i];j ++) {
				if (stuop[j] ^ st[i][j]) {
					wrong[i] ++;
					mx_wrong = max (wrong[i], mx_wrong);
					flag = 1;
					break;
				}
			}
			if (!flag) sum += score[i];
			getchar (); getchar ();
		}
		cout << sum << endl;
	}
	
	if (mx_wrong == 0) return puts ("Too simple"), 0;
	
	cout << mx_wrong;
	for (int i = 1;i <= m;i ++)
	if (mx_wrong == wrong[i]) cout << ' ' << i;
	
	return 0;
}

1059 C语言竞赛 (20 分)

#include
using namespace std;
const int N = 1e5+10;

int n, id, rk[N], st[N];

bool isprime (int x) {
	if (x <= 1) return false;
	for (int i = 2;i <= x/i;i ++)
	if (x % i == 0) return false;
	return true;
}
int main()
{
	cin >> n;
	for (int i = 1;i <= n;i ++) {
		cin >> id;
		rk[id] = i;
	}
	cin >> n;
	while (n --) {
		cin >> id;
		printf ("%04d: ", id);
		if (st[id]) cout << "Checked" << endl;
		else {
			st[id] = 1;
			if (rk[id] == 1) cout << "Mystery Award" << endl;
			else if (isprime (rk[id])) puts ("Minion");
			else if (rk[id]) puts ("Chocolate");
			else st[id] = 0, puts ("Are you kidding?");
		} 
	}

	return 0;
}

1060 爱丁顿数 (25 分)

我用的yxc模板进行的二分。

注意坑点:r要初始化为n,因为有可能全部天数都被选上

#include
using namespace std;
const int N = 1e5+10;
int n, a[N];

bool check (int x) {
	int res = 0;
	for (int i = 0;i < n;i ++) if (a[i] > x) res ++;
	return res >= x;
}

int main()
{
	cin >> n;
	for (int i = 0;i < n;i ++) cin >> a[i];
	
	int l = 0, r = n, mid; // r要初始化为n,因为有可能全部天数都被选上 
	while (l < r) {
		mid = l + r + 1 >> 1;
		if (check (mid)) l = mid;
		else r = mid - 1;
	}	
	
	cout << l << endl;

	return 0;
}

1061 判断题 (15 分)

#include
using namespace std;
int n, m, as, w[110], r[110];
int main()
{
	cin >> n >> m;
	for (int i = 1;i <= m;i ++) cin >> w[i];
	for (int i = 1;i <= m;i ++) cin >> r[i];
	while (n --) {
		int s = 0;
		for (int i = 1;i <= m;i ++) 
			cin >> as,
			s += (as == r[i]) * w[i];
		cout << s << endl;
	}	

	return 0;
}

1062 最简分数 (20 分)

#include
using namespace std;
typedef long long LL;
LL a, b, x, y, m;

int main()
{
	scanf ("%lld/%lld %lld/%lld %lld", &a, &b, &x, &y, &m);
	if (1.0 * a / b > 1.0 * x / y) swap(a, x), swap (b, y); // 一个测试点 
	
	LL mu = b * y / __gcd (b, y);
	mu = mu * m /  __gcd (mu, m); // 计算三个分母的最小公倍数 
	LL aa = mu / b * a, xx = mu / y * x; // aa为左端点的数以mu为分母时的分子,xx为右端点的数以mu为分母时的分子 
	
	int flag = 0;
	for (LL i = aa+1;i < xx;i ++) // 枚举分子 
	if (mu / __gcd (i, mu) == m) { // 如果能保证分母为m时最简 ,即m为i和mu的最大公因子 
		if (flag) cout << ' '; 
		flag = 1;
		cout << i / __gcd (i, mu) << '/' << m; // 除以最大公因子 
	}
	
	return 0;
}

1063 计算谱半径 (20 分)

#include
using namespace std;

double ans = -1.0;
int main()
{
	int n;
	cin >> n;
	while (n --) {
		double a, b;
		cin >> a >> b;
		double c = sqrt (pow (a, 2) + pow (b, 2));
		ans = max (ans, c);	
	}	
	printf ("%.2lf\n", ans);
	return 0;
}

1064 朋友数 (20 分)

#include
using namespace std;
int n, ans, x, cnt[10000];
int main()
{
	cin >> n;
	while (n --) {
		cin >> x;
		int t = 0;
		while (x) {
			t += x % 10;
			x/=10;
		}
		cnt[t] ++;
		if (cnt[t] == 1) ans ++;
	}	
	cout << ans << endl;
	int flag = 0;
	for (int i = 0;i <= 36;i ++) 
		if (cnt[i] >= 1) {
			if (flag) cout << ' ';
			flag = 1;
			cout << i;
		}
	return 0;
}

1065 单身狗 (25 分)

#include
using namespace std;
const int N = 1e6+10;
int n, m, a, b;
int e[N], st[N], c[N];
vector <int> ans;
int main()
{
	cin >> n;
	while (n--) {
		cin >> a >> b;
		e[a] = b;
		e[b] = a;
	}	
	
	cin >> m;
	for (int i = 1;i <= m;i ++) cin >> c[i], st[c[i]] = 1;
	
	for (int i = 1;i <= m;i ++)
	if (!st[e[c[i]]]) ans.push_back (c[i]);
	
	sort (ans.begin(), ans.end());
	
	cout << ans.size() << endl;
	if (ans.size()) {
		printf ("%05d", ans[0]);
		for (int i = 1;i < ans.size();i ++) printf (" %05d", ans[i]);
	}

	return 0;
}

1066 图像过滤 (15 分)

用sca

#include
using namespace std;

int main()
{
	int n, m, a, b, t;
	scanf ("%d%d%d%d%d", &n, &m, &a, &b, &t);
	
	for (int i = 1;i <= n;i ++, cout << endl) {
		int flag = 0;
		for (int j = 1;j <= m;j ++) {
			if (flag) cout << ' ';
			flag = 1;
			int x;
			scanf ("%d", &x);
			if (x >= a && x <= b) printf ("%03d", t);
			else printf ("%03d", x);
		}	
	}

	return 0;
}

1067 试密码 (20 分)

不知道为什么这道题正确率这么低。

#include
using namespace std;

int main()
{
	string password, s;
	int n, wrong_cnt = 0;
	cin >> password >> n;
	getchar ();
	while (getline (cin, s) && s != "#") {
		if (s == password) return puts ("Welcome in"), 0;
		else {
			wrong_cnt ++;
			printf ("Wrong password: %s\n", s.c_str());
			if (wrong_cnt == n) return puts ("Account locked"), 0;
		}
	}
	return 0;
}

1068 万绿丛中一点红 (20 分)

#include
using namespace std;
const int N = 1100;
typedef long long LL;
LL n, m, thres;
LL ansx, ansy, c[N][N];
map <LL, int> cnt;

bool check (int x, int y) {
	for (int i = x-1;i <= x+1;i ++)
	for (int j = y-1;j <= y+1;j ++) {
		if (i < 1 || y < 1 || x > n || y > m) continue;
		if (x == i && y == j) continue;
		if (abs (c[i][j] - c[x][y]) <= thres) return false;
	}
	return true;
}

int main()
{
	cin >> m >> n >> thres;
	for (int i = 1;i <= n;i ++)
	for (int j = 1;j <= m;j ++) 
	cin >> c[i][j], cnt[c[i][j]] ++;

	for (int i = 1;i <= n;i ++)
	for (int j = 1;j <= m;j ++) {
		if (cnt[c[i][j]] == 1 && check (i, j)) {
			if (ansx && ansy) return puts ("Not Unique"), 0;
			ansx = i, ansy = j;
		}
	}
	if (ansx && ansy) printf ("(%d, %d): %lld", ansy, ansx, c[ansx][ansy]);
	else puts ("Not Exist");
	return 0;
}

1069 微博转发抽奖 (20 分)

#include
using namespace std;
int n, m, s;
string a[1100];
map <string, int> st;
int main()
{
	cin >> m >> n >> s;
	if (s > m) return puts ("Keep going..."), 0;
	for (int i = 1;i <= m;i ++) cin >> a[i];
	
	for (int i = s;i <= m;i += n) {
		while (i <= m && st[a[i]]) i ++;
		st[a[i]] = 1;
		cout << a[i] << endl;
	}

	return 0;
}

1070 结绳 (25 分)

#include
using namespace std;
const int N = 1e4+10;
double ans, a[N];
int n;
int main()
{
	cin >> n;
	for (int i = 1;i <= n;i ++) cin >> a[i];
	sort (a + 1, a + 1 + n);
	
	for (int i = 2;i <= n;i ++) ans += a[i] / pow (2, n-i+1);
	ans += a[1] / pow (2, n-1);
	
	cout << (int)ans << endl;

	return 0;
}

1071 小赌怡情 (15 分)

小赌也不怡情哦~

#include
using namespace std;

int main()
{
	int T, K, flag;
	cin >> T >> K;
	
	while (K --) {
		int n1, b, t, n2;
		cin >> n1 >> b >> t >> n2;
		if (t > T) {
			printf ("Not enough tokens.  Total = %d.\n", T);
			continue;
		}
		if ((n1 < n2) ^ b) flag = -1;
		else flag = 1;
		if (flag == 1) printf ("Win %d!  Total = %d.\n", t, T += t);
		else printf ("Lose %d.  Total = %d.\n", t, T -= t);
		if (T == 0) return cout << "Game Over.", 0;
	}	

	return 0;
}

1072 开学寄语 (20 分)

一定注意输出编号的时候位数的控制。

#include
using namespace std;

int ans1, ans2;
map <int, int> mp;

int main()
{
	int n, m, id;
	cin >> n >> m;
	while (m --) {
		cin >> id;
		mp[id] = 1;
	}
	for (int i = 1;i <= n;i ++) {
		int flag = 0;
		string name;
		int k, good;
		cin >> name;
		cin >> k;
		while (k --) {
			cin >> good;
			if (mp[good]) {
				if (!flag) ans1 ++, cout << name << ':';
				flag = 1;
				ans2 ++;
				printf (" %04d", good); // 一个测试点 
			}
		}
		if (flag) cout << endl;
	}
	
	cout << ans1 << ' ' << ans2 << endl;
	
	return 0;
}

1073 多选题常见计分法 (20 分)

真题真麻烦啊。

注意某个题的某个选项出错的次数是漏选之与多(错)选之之和。

#include
using namespace std;

const int N = 1100;

int n, m;
int num[N], right_num[N], st[N][10], mx_wrong, wrong[N][10], tmp[10];
double score[N];

int main()
{
	cin >> n >> m;
	for (int i = 1;i <= m;i ++) {
		cin >> score[i] >> num[i] >> right_num[i]; // 第i个题的分数,第i个题的全部选项个数,第i个题的正确选项个数 
		for (int j = 1;j <= right_num[i];j ++) {
			char op;
			cin >> op;
			st[i][op - 97] = 1; // st记录标准答案,st[i][j]表示第i题的第j个选项选还是不选 
		}
	}	
	getchar ();
	while (n --) {
		double sum = 0;
		for (int i = 1;i <= m;i ++) {
			int flag = 0, right_cnt = 0, k;
			getchar (); // 去掉( 
			scanf ("%d", &k);
			memset (tmp, 0, sizeof tmp);
			for (int j = 1;j <= k;j ++) { 
				char op;
				cin >> op;
				tmp[op - 97] = 1; // 记录下当前同学的第i个题的j选项是否选了 
			}
			for (int j = 1;j <= num[i];j ++) {
				if (st[i][j-1] ^ tmp[j-1]) {
					if (st[i][j-1] == 0) flag = 1; // flag=1表示错选直接零分,flag=0表示全选或选部分 
					wrong[i][j-1] ++; // 记录全部同学第i个题的该选项错误 
					mx_wrong = max (wrong[i][j-1], mx_wrong); // 找到最多错误次数 
				} else if (st[i][j-1] == 1) right_cnt ++; // 统计选对的个数 
			}
			if (k == 0 || flag == 1) ; // 选了0个或者是错选,0分 
			else if (right_cnt < right_num[i]) sum += 0.5 * score[i]; // 选部分 50% 
			else sum += score[i]; // 全对 
			getchar ();getchar (); // 去掉)和空格 
		}
		printf ("%.1lf\n", sum); // 得分 
	}

	if (mx_wrong == 0) return cout << "Too simple" << endl, 0; // 最大错误次数是0 
	for (int i = 1;i <= m;i ++)
	for (int j = 1;j <= num[i];j ++)
	if (mx_wrong == wrong[i][j - 1]) cout << mx_wrong << ' ' << i << '-' << char (96 + j) << endl;
	// 遍历全部题目的全部选项,如果该选项错误次数等于最大次数,输出。 
	
	return 0;
}

1074 宇宙无敌加法器 (20 分)

#include
using namespace std;

int main()
{
	string tab, s1, s2;
	cin >> tab >> s1 >> s2;
	reverse (tab.begin (), tab.end ());
	reverse (s1.begin (), s1.end ());
	reverse (s2.begin (), s2.end ());
	int n = s1.size(), m = s2.size();
	int len = max (n, m);
	vector <int> c(len + 1);
	tab += string (100000, '0');
	while (s1.size() < len) s1 += '0';
	while (s2.size() < len) s2 += '0';
// 	cout << s1 << endl << s2 << endl;
	for (int i = 0;i < max (n, m);i ++) {
		int mod = tab[i] - '0';
		if (mod == 0) mod = 10;
		c[i] += (s1[i] - '0') + (s2[i] - '0');
		c[i+1] += c[i] / mod;
		c[i] %= mod;
// 		cout << c[i] << endl;
	}	
	
	if (c[len]) len ++;
// 	cout << len << endl;
	int i = len-1;
	while (i >= 1 && c[i] == 0) i --; 
	for (;i >= 0;i --) cout << c[i];	

	return 0;
}

1075 链表元素分类 (25 分)

题解链接

1076 Wifi密码 (15 分)

#include
using namespace std;

int main()
{
	int n;
	string s;
	cin >> n;
	getchar ();
	while (n --) {
		getline (cin, s);
		cout << s[s.find ('T') - 2] - 64;
	}	

	return 0;
}

1077 互评成绩计算 (20 分)

#include
using namespace std;

int main()
{
	int n, m;
	cin >> n >> m;
	for (int i = 1;i <= n;i ++) {
		double ts, sum = 0, x, mx = -1, mn = 1000000;
		int cnt = 0;
		cin >> ts;
		for (int j = 1;j < n;j ++) {
			cin >> x;
			if (x < 0 || x > m) continue;
			cnt ++;
			sum += x;
			mx = max (mx, x);
			mn = min (mn, x);
		}
		sum -= mx + mn;
		cnt -= 2;
		cout << int ((sum / cnt + ts) / 2 + 0.5) << endl;
	}	

	return 0;
}

1078 字符串压缩与解压 (20 分)

#include
using namespace std;

int main()
{
	int cnt = 1;
	char op;
	string s;
	cin >> op; getchar ();
	getline (cin, s);
	if (op == 'C') { // 压缩 
		for (int i = 1;i < s.size();i ++) {
			if (s[i] == s[i-1]) cnt ++;
			else {
				if (cnt != 1) cout << cnt;
				cout << s[i-1];
				cnt = 1;
			}
		}
		if (cnt != 1) cout << cnt;
		cout << s[s.size()-1];
	} else { // 解压缩 
		for (int i = 0;i < s.size();i ++) {
			int num = 0;
			while (i < s.size() && isdigit (s[i])) num = num * 10 + (s[i] - '0'), i ++;
			if (num == 0) cout << s[i];
			else for (int j = 0;j < num;j ++) cout << s[i];
		}
	}

	return 0;
}

1079 延迟的回文数 (20 分)

高精度加法而已。

#include
using namespace std;

bool check (string s) {
	int r = s.size()-1, l = 0;
	while (l < r) {
		if (s[l] != s[r]) return false;
		l ++, r --;
	}
	return true;
}

string add (string s1, string s2) {
	string res = "";
	int n = s1.size(), m = s2.size();
	reverse (s1.begin (), s1.end ());
	reverse (s2.begin (), s2.end ());
	int len = max (n, m);
	vector <int> a, b, c(len + 1);
	for (int i = 0;i < n;i ++) a.push_back (s1[i] - '0');
	for (int i = 0;i < m;i ++) b.push_back (s2[i] - '0');
	
	for (int i = 0;i < len;i ++) {
		c[i] += a[i] + b[i];
		c[i+1] += c[i] / 10;
		c[i] %= 10;
	}
	
	if (c[len]) len ++;
	for (int i = len-1;i >= 0;i --) res += c[i] + '0';
	return res;
}

int main()
{
	string s;
	cin >> s;
	int T = 10;
	while (T --) {
		if (check (s)) return cout << s << " is a palindromic number.", 0;
		string s_re = s, tmp;
		reverse (s_re.begin(), s_re.end());
		cout << (s) << " + " << (s_re) << " = " << (tmp = add (s, s_re)) << endl;
		s = tmp;
	}
	puts ("Not found in 10 iterations.");
	return 0;
}

1080 MOOC期终成绩 (25 分)

题目写的我服了啊!
在这里插入图片描述
???;否则 ???

#include
using namespace std;
const int NN = 10010 * 3;
int P, M, N, idx;

map <string, int> st;

struct students {
	string name;
	int p = -1;
	double m = -1, f = -1;
	int g; 
} stu[NN];

bool cmp (students a, students b) {
	if (a.g != b.g) return a.g > b.g;
	return a.name < b.name;
}

void getinfo (int n, int op) {
	string id;
	double s;
	for (int i = 0;i < n;i ++) {
		cin >> id >> s;
		int t = (st.count(id) ? st[id] : (st[id] = idx ++));
		stu[t].name = id;
		
		if (op == 0) stu[t].p = int(s);
		else if (op == 1) stu[t].m = s;
		else stu[t].f = s;
	}
}

int main()
{
	cin >> P >> M >> N;
	
	getinfo (P, 0);
	getinfo (M, 1);
	getinfo (N, 2);
	
	for (int i = 0;i < idx;i  ++) 
	stu[i].g = int((stu[i].m <= stu[i].f ? stu[i].f :(0.4 * (stu[i].m == -1 ? 0 : stu[i].m) + 0.6 * stu[i].f)) + 0.5);
	
	sort (stu, stu + idx, cmp);
	
	for (int i = 0;i < idx;i ++)
	if (stu[i].p >= 200 && stu[i].g >= 60) 
	cout << stu[i].name << ' ' << stu[i].p << ' ' << stu[i].m << ' ' << stu[i].f << ' ' << stu[i].g << endl;
	
	return 0;
}

1081 检查密码 (15 分)

#include
using namespace std;

string s;
int n;

int judge () {
	int num = 0, character = 0;
	for (int i = 0;i < s.size();i ++) {
		if (isalpha (s[i])) character  =1;
		else if (isdigit (s[i])) num = 1;
		else if (s[i] != '.') return 1;
	}
	if (num == 0) return 2;
	if (character == 0) return 3;
	return 0;
}

int main()
{
	cin >> n;
	getchar ();
	while (n --) {
		getline (cin, s);
		if (s.size() < 6) puts ("Your password is tai duan le.");
		else {
			int res = judge ();
			if (res == 1) puts ("Your password is tai luan le.");
			else if (res == 2) puts ("Your password needs shu zi.");
			else if (res == 3) puts ("Your password needs zi mu.");
			else puts ("Your password is wan mei.");
		}
	}	

	return 0;
}

1082 射击比赛 (20 分)

#include
using namespace std;
int n, id, x, y, mx = -1, mn = 100 * 100 * 2 + 1, ans_mx, ans_mn;
int main()
{
	cin >> n;
	while (n --) {
		cin >> id >> x >> y;
		int s = x * x + y * y;
		if (s > mx) mx = s, ans_mx = id;
		if (s < mn) mn = s, ans_mn = id;
	}	
	
	printf ("%04d %04d\n", ans_mn, ans_mx);

	return 0;
}

1083 是否存在相等的差 (20 分)

#include
using namespace std;

int n, cnt[10100], x;

int main()
{
	cin >> n;
	for (int i = 1;i <= n;i ++) cin >> x, cnt[abs (i - x)] ++;
	for (int i = n-1;i >= 0;i --)
	if (cnt[i] > 1) cout << i << ' ' << cnt[i] << endl;

	return 0;
}

1084 外观数列 (20 分)

#include
using namespace std;

int main()
{
	int n;
	string d;
	cin >> d >> n;
	while (-- n) {
		string res = "";
		int cnt = 1;
		for (int i = 1;i < d.size();i ++) {
			if (d[i] == d[i-1]) cnt ++;
			else res += d[i-1], res += cnt + '0', cnt = 1;
		}
		res += d[d.size()-1], res += cnt + '0';
		d = res;
//		cout << res << endl;
	}	
	cout << d << endl;
	return 0;
}

1085 PAT单位排行 (25 分)

注意最后一个测试点要改double啥的。

#include
using namespace std;
const int N = 1e5+10;
struct Rank {
	string school;
	double score; // 改double
	int cnt;
} rank_[N];

bool cmp (Rank a, Rank b) {
	if ((int)a.score != (int)b.score) return a.score > b.score; // 改int 
	if (a.cnt != b.cnt) return a.cnt < b.cnt;
	return a.school < b.school;
}

int n;
double s;  // 改double
string id, sch;

map <string, pair <double, int> > school; // 改double 

int main()
{
	cin >> n;
	while (n --) {
		cin >> id >> s >> sch;
		if (id[0] == 'T') s *= 1.5;
		else if (id[0] == 'B') s /= 1.5;
		transform (sch.begin(), sch.end(), sch.begin(), ::tolower);
		school[sch].first += s;
		school[sch].second ++;
	} 
	
	int cnt = 0;
	for (auto item : school) {
		cnt ++;
		rank_[cnt].school = item.first;
		rank_[cnt].score = item.second.first;
		rank_[cnt].cnt = item.second.second;
	}

	sort (rank_+1, rank_+cnt+1, cmp);
	
	cout << cnt << endl;
	
	int rk = 2, trk = 1;
	cout << trk << ' ' << rank_[1].school <<' ' << (int)rank_[1].score << ' ' << rank_[1].cnt << endl; // 改int
	for (int i = 2;i <= cnt;i ++, rk ++) {
		if ((int)rank_[i].score != (int)rank_[i-1].score) cout << rk << ' ', trk = rk; // 改int
		else cout << trk << ' ';
		cout << rank_[i].school <<' ' << (int)rank_[i].score << ' ' << rank_[i].cnt << endl; // 改int
	}
	return 0;
}

1086 就不告诉你 (15 分)

我靠,怪不得正确率不是特别高,有些情况要考虑到:

  1. 1000,倒过来是1
  2. 2010,倒过来是102
    还考虑到了负数,但是题目说了是正整数。
#include
using namespace std;

int main()
{
	int a, b;
	cin >> a >> b;
	int x = a * b;
	int flag = 0;
	while (x) {
		if (x%10 || flag) flag = 1, cout << x%10;
		x/=10;
	}	
	if (!flag) cout << 0;
	return 0;
}

1087 有多少不同的值 (20 分)

#include
using namespace std;
int n, ans, st[1000010];
int main()
{
	cin >> n;
	for (int i = 1;i <= n;i ++)
	if (!st[i/2 + i/3 + i/5]) ans ++, st[i/2 + i/3 + i/5] = 1;
	cout << ans << endl;

	return 0;
}

1088 三人行 (20 分)

坑点:丙不一定是整数!

#include
using namespace std;

string judge (double x, double y) {
	if (x == y) return "Ping";
	if (x > y) return "Gai";
	return "Cong";
}

double m, x, y;

int main()
{
	cin >> m >> x >> y;
	
	for (int i = 99;i >= 10;i --) {
		int a = i;
		int b = i % 10 * 10 + i / 10;
		double c = abs (a - b) * 1.0 / x;
		if (b == y * c) 
		return cout << a << ' ' << judge (m, a) << ' ' << judge (m, b) << ' ' << judge (m, c), 0;
	}
	puts ("No Solution");
	return 0;
}

1089 狼人杀-简单版 (20 分)

卧槽,柳神水平确实牛皮!

题解链接

1090 危险品装箱 (25 分)

#include
using namespace std;
const int N = 1e4+10, M = 1e6+10;
int e[N<<2], ne[N<<2], h[M], idx;
int st[M], g[N];

void add (int a, int b) {
	e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}

int main()
{
	memset (h, -1, sizeof h);
	
	int n, m, a, b, k;
	cin >> n >> m;
	while (n --) {
		cin >> a >> b;
		add (a, b);
		add (b, a);
	}	
	
	while (m --) {
		cin >> k;
		int flag = 0;
		memset (st, 0, sizeof st);
		for (int i = 0;i < k;i ++) cin >> g[i], st[g[i]] = 1;
		for (int i = 0;i < k;i ++) {
			int x = g[i];
			for (int j = h[x];~j;j = ne[j]) {
				int t = e[j];
				if (st[t]) {
					flag = 1;
					break;
				}
			}
			if (flag) break;
		}
		if (flag) puts ("No");
		else puts ("Yes");
	}

	return 0;
}

1091 N-自守数 (15 分)

#include
using namespace std;

bool check (int x, int t) {
	int tx = t*x*x;
	while (x) {
		if (x % 10 != tx % 10) return false;
		x /= 10;
		tx /= 10;
	}
	return true;
}

int main()
{
	int n;
	cin >> n;
	while (n --) {
		int x, flag = 0;
		cin >> x;
		for (int i = 0;i < 10;i ++)
			if (check (x, i)) {
				cout << i << ' ' << i * x * x << endl;
				flag = 1;
				break;
			}
		if (!flag) puts ("No");
	}

	return 0;
}

1092 最好吃的月饼 (20 分)

#include
using namespace std;

int ans = -1, res = -1, n, m, x, cnt[1100];

int main()
{
	cin >> n >> m;
	while (m --) {
		for (int i = 1;i <= n;i ++) {
			cin >> x;
			cnt[i] += x;
			res = max (cnt[i], res);
		}
	}	

	cout << res << endl;
	
	int flag = 0;
	for (int i = 1;i <= n;i ++) {
		if (res == cnt[i]) {
			if (flag) cout << ' ';
			cout << i;
			flag = 1;
		}
	}
	
	return 0;
}

1093 字符串A+B (20 分)

#include
using namespace std;
int st[1100];
int main()
{
	string s1, s2;
	getline (cin, s1);
	getline (cin, s2);
	
	for (int i = 0;i < s1.size();i ++)
	if (!st[s1[i]]) cout << s1[i], st[s1[i]] = 1;
	for (int i = 0;i < s2.size();i ++)
	if (!st[s2[i]]) cout << s2[i], st[s2[i]] = 1;
	return 0;
}

1094 谷歌的招聘 (20 分)

#include
using namespace std;
typedef long long LL;
string s;
int n, k;

bool isprime (LL x) {
	if (x <= 1LL) return false;
	for (LL i = 2LL;i <= x/i;i ++) 
		if (x % i == 0LL) return false;
	return true;
}

int main()
{
	scanf ("%d %d", &n, &k);
	cin >> s;
	
	if (s.size() < k) return puts("404"), 0; // 一个测试点 
	
	for (int i = 0;i <= s.size()-k;i ++) {
		string ss = s.substr (i, k);
		LL t = atoll (ss.c_str ());
		if (isprime (t)) return cout << ss, 0;
	}
	puts ("404");
	
	return 0;
}

1095 解码PAT准考证 (25 分)

用STL不会超时,但是用cin和cout会超时,要用scanf和printf!!!


一开始我以为是因为我的每次询问都排序导致超时,所以将在线处理改为离线了,预处理排序,最后测试点3还是超时,其实应该不是这个原因,M才10不至于。

使用cin cout最多将最后一个测试点优化到190s,但是测试点3还是过不去,看了别人的博客发现其实根本原因在于使用scanf和printf,瞬间耗时降低到了两位数。

#include
using namespace std;

map <char, int> char2num = {{'T', 0}, {'A', 1}, {'B', 2}};
map <pair <int, int>, int> st;
set <int> date_set;

struct node1 {
	string id;
	int s;
};

bool cmp1 (node1 a, node1 b) {
	if (a.s != b.s) return a.s > b.s;
	return a.id < b.id;
}

struct node2 {
	int cnt, sum;
};

struct node3 {
	int rmid, cnt;
};

bool cmp3 (node3 a, node3 b) {
	if (a.cnt != b.cnt) return a.cnt > b.cnt;
	return a.rmid < b.rmid;
}

struct operations {
	int op;
	string s;
} operation[110];

vector <node1> tps[3];
node2 rms[1100];
vector <node3> dts[1000010];

int main()
{
	int n, m;
	cin >> n >> m;
	for (int i = 1;i <= n;i ++) {
		string id; id.resize(13);
		int s;
		scanf ("%s %d", &id[0], &s);
		int type = char2num[id[0]];
		int roomid = atoi(id.substr (1, 3).c_str ());
		int date = atoi(id.substr (4, 6).c_str ());
		int stuid = atoi(id.substr (10).c_str ());
		tps[type].push_back ({id, s}); // op1
		rms[roomid].cnt ++, rms[roomid].sum += s; // op2
		date_set.insert (date);
		if (!st[{date, roomid}]) dts[date].push_back ({roomid, 1}), st[{date, roomid}] = dts[date].size(); // op3
		else dts[date][st[{date, roomid}]-1].cnt ++; // op3;
	}
	
	// 预处理排序
	for (int i = 0;i < 3;i ++) sort (tps[i].begin(), tps[i].end(), cmp1);

	// 离线处理	
	for (int i = 1;i <= m;i ++) {
		int op;
		string s;
		s.resize(13);
		scanf ("%d %s", &op, &s[0]);
		operation[i] = {op, s};
		if (op == 3) date_set.insert (atoi (s.c_str()));
	}
	
	for (auto d : date_set) 
		if (dts[d].size()) 
			sort (dts[d].begin (), dts[d].end (), cmp3);
	
	for (int i = 1;i <= m;i ++) {
		int op = operation[i].op;
		string s = operation[i].s; 
		printf ("Case %d: %d %s\n", i, op, s.c_str());
		
		if (op == 1) { // op1
			int type = char2num[s[0]];
			if (tps[type].size() == 0) 
				printf ("NA\n");
			else 
				for (int j = 0;j < tps[type].size();j ++)
					printf ("%s %d\n", tps[type][j].id.c_str(), tps[type][j].s);
		} else if (op == 2) { // op2
			int roomid = atoi (s.c_str ());
			if (rms[roomid].cnt == 0) 
				printf ("NA\n");
			else 
				printf ("%d %d\n", rms[roomid].cnt, rms[roomid].sum);
		} else { // op3
			int date = atoi (s.c_str ());
			if (dts[date].size() == 0) 
				printf ("NA\n");
			else 
				for (int j = 0;j < dts[date].size();j ++) 
					printf ("%d %d\n", dts[date][j].rmid, dts[date][j].cnt);
		}
	}
	return 0;
}

1096 大美数 (15 分)

这也太暴力了吧。

试除法求全部约数的模板

#include
using namespace std;

bool isbu (int x) {
	vector <int> factors;
	for (int i = 1;i <= x/i;i ++) {
		if (x % i == 0) {
			factors.push_back (i);
			if (x / i != i) factors.push_back (x / i);
		}
	}
	
	int n = factors.size();
//	cout << n << endl;
//	for (int i = 0;i < n;i ++) cout << factors[i] << ' ';
//	cout << endl;
	if (n < 4) return false;
	for (int a = 0;a < n;a ++)
	for (int b = a+1;b < n;b ++)
	for (int c = b+1;c < n;c ++)
	for (int d = c+1;d < n;d ++) 
	if ((factors[a]+factors[b]+factors[c]+factors[d]) % x == 0) return true;
		
	return false;
	
}

int main()
{
	int n, k;
	cin >> n;
	while (n --) {
		cin >> k;
		if (isbu (k)) puts ("Yes");
		else puts ("No");
	}	

	return 0;
}

1097 矩阵行平移 (20 分)

(凭一己之力拉低正确率)

#include
using namespace std;

int n, k, x, a[110][110], cnt[110];

int main()
{
	cin >> n >> k >> x;
	for (int i = 1;i <= n;i ++)
	for (int j = 1;j <= n;j ++)
	cin >> a[i][j];
	
	for (int i = 1, t = 1;i <= n;i += 2, t ++) {
		if (t == k + 1) t = 1;
		for (int j = n;j > t;j --) a[i][j] = a[i][j-t];
		for (int j = 1;j <= t;j ++) a[i][j] = x;
		for (int j = 1;j <= n;j ++) cnt[j] += a[i][j];
	}
	
	for (int i = 2;i <= n;i += 2)
	for (int j = 1;j <= n;j ++)
	cnt[j] += a[i][j];
	
	int flag = 0;
	for (int i = 1;i <= n;i ++) {
		if (flag) cout << ' ';
		cout << cnt[i];
		flag = 1;
	}
	
	return 0;
}

1098 岩洞施工 (20 分)

至少需要削掉的高度,不是指多个高出来的都要加起来,而是高出来的高度取max。

举个例子,两处红色部分都是高出的部分,要保证一个方格宽度的道路就必须把最高的那个去掉,而小的那么也会被同时去掉;当然不一定非要选绿色道路作为目标,也可以选其上面那行,原理一样结果一样。

PAT (Basic Level) Practice (中文)题目集合_第1张图片

#include
using namespace std;
int up = 1100, down = -1;
int main()
{
	int n;
	cin >> n;
	for (int i = 0;i < n;i ++) {
		int u;
		cin >> u;
		up = min (u, up);
	}
	for (int i = 0;i < n;i ++) {
		int d;
		cin >> d;
		down = max (d, down);
	}
	int ans = up - down, flag = 0;
	if (ans >= 1) cout << "Yes" << ' ';
	else cout << "No" << ' ', flag = 1;
	cout << abs (ans) + flag << endl;
	return 0;
}

1099 性感素数 (20 分)

#include
using namespace std;

bool isprime (int x) {
	if (x <= 1) return false; // ! 
	for (int i = 2;i <= x / i;i ++)
		if (x % i == 0) return false;
	return true;
}

int main()
{
	int n;
	cin >> n;
	if (isprime (n) && isprime(n-6)) puts ("Yes"), cout << n-6 << endl;
	else if (isprime (n) && isprime(n+6))	puts ("Yes"), cout << n+6 << endl;
	else {
		puts ("No");
		for (int i = n+1;;i ++) {
			if (isprime (i) && ((i < n+6 && isprime (i-6)) || isprime (i+6))) // i < n+6 是为了减少冗余计算 
				return cout << i, 0;
		}
	}

	return 0;
}

1100 校庆 (25 分)

#include
using namespace std;

int n, cnt;
string id, ans = "", ans_bu = "";
map<string, int> mp;

int main()
{
	cin >> n;
	while (n --) {
		cin >> id;
		mp[id] = 1;
	}	
	
	cin >> n;
	while (n --) {
		cin >> id;
		if (mp[id]) {
			if (ans == "" || id.substr (6, 8) < ans.substr (6, 8)) ans = id;
			cnt ++;
		}
		if (ans_bu == "" || id.substr (6, 8) < ans_bu.substr (6, 8)) ans_bu = id;
	}
	
	cout << cnt << endl;
	if (ans == "") cout << ans_bu;
	else cout << ans << endl;
	return 0;
}

1101 B是A的多少倍 (15 分)

#include 
typedef long long LL;
using namespace std;
int main () {
    string s;
    int d;
    cin >> s >> d;
    LL a = atoll (s.c_str());
    LL b = atoll ((s.substr (s.size() - d, d) + s).substr (0, s.size()).c_str());
    printf ("%.2lf\n", 1.0 * b / a);
}

1102 教超冠军卷 (20 分)

#include
using namespace std;

string ans_sale, ans_cnt, id;
int mx_sale=-1, mx_cnt=-1, m, cnt, n; // 初始化为-1,PTA中很多都是存在0的情况 


int main()
{
	cin >> n;
	while (n --) {
		cin >> id >> m >> cnt;
		if (m * cnt > mx_sale) {
			ans_sale = id;
			mx_sale = m * cnt;
		}
		if (cnt > mx_cnt) {
			ans_cnt = id;
			mx_cnt = cnt;
		}
	}	
	cout << ans_cnt << ' ' << mx_cnt << endl;
	cout << ans_sale << ' ' << mx_sale << endl;	
	

	return 0;
}

1103 缘分数 (20 分)

坑点:最后一个测试点“其中 a 和它的小弟 a−1 的立方差正好是一个整数 c 的平方”。

#include
using namespace std;
typedef long long LL; // 好像可以不开longlong 
LL l, r;
vector<pair<LL,LL> > ans;

int main()
{
	cin >> l >> r;
	
	for (LL i = l;i <= r;i ++) {
		LL a = i, b = -1;
		LL c = a*a*a - (a-1LL)*(a-1LL)*(a-1LL);
		if (c != LL(sqrt(c)) * LL(sqrt(c))) continue;
		c = sqrt (c);
		if (c == a) continue; // 最后一个测试点 
		for (LL j = 1LL;j <= r;j ++) {
			LL tc = j * j + (j-1LL) * (j-1LL);
			if (tc >= c) {
				if (tc == c) b = j;
				break;
			}
		}
		if (b != -1LL) ans.push_back ({a, b});
	}	

	if (ans.size()) {
		for (int i = 0;i < ans.size(); i++) 
			cout << ans[i].first << ' ' << ans[i].second << endl;
	} else {
		puts ("No Solution");
	}
	
	return 0;
}

1104 天长地久 (20 分)

题解链接

1105 链表合并 (25 分)

题解链接

1106 2019数列 (15 分)

有可能n<4

#include
using namespace std;

int n;
int ans[4] = {2, 0, 1, 9};

int main()
{
	cin >> n;
	int cnt = 4;
	
	int sum = 2 + 0 + 1 + 9;
	
	for (int i = 0;i < min (4, n);i ++) cout << ans[i];
		
	if (n > 4) 
		while (cnt != n) {
			int sum = 0;
			for (int i = 0;i < 4;i ++) sum += ans[i], ans[i] = ans[i+1];
			ans[3] = sum % 10;
			cout << ans[3];
			cnt ++;
		}
	
	return 0;
}

1107 老鼠爱大米 (20 分)

#include
using namespace std;

int n, m, x, ans = -1;
int mx[110];

int main()
{
	memset (mx, -1, sizeof mx);
	cin >> n >> m;
	for (int i = 0;i < n;i ++) 
		for (int j = 0;j < m;j ++)
			cin >> x, 
			mx[i] = max (mx[i], x), 
			ans = max (mx[i], ans);	
	
	cout << mx[0];
	for (int i = 1;i < n;i ++) cout << ' ' << mx[i];
	cout << endl << ans;

	return 0;
}

1108 String复读机 (20 分)

做过至少三次了吧。

#include
using namespace std;

string mp = "String";
int cnt[1000];
string s;

int main()
{
	getline (cin, s);
	for (int i = 0;i < s.size();i ++)
	cnt[s[i]] ++;
	
	while (1) {
		int flag = 0;
		for (int i = 0;i < mp.size();i ++)
			if (cnt[mp[i]]) cnt[mp[i]] --, cout << mp[i], flag |= cnt[mp[i]];
		if (!flag) break;
	}
		

	return 0;
}

1109 擅长C (20 分)

#include
using namespace std;

string zimu[30][10];
string s;

int main()
{
	for (int i = 0;i < 26;i ++) {
		for (int j = 0;j < 7;j ++)
			cin >> zimu[i][j];
	}	
	
	int enter = 0;
	getchar ();
	getline (cin, s);
	for (int i = 0;i < s.size();i ++) {
		if ('A' <= s[i] && s[i] <= 'Z') {
			int j = i;
			while (j < s.size() && 'A' <= s[j] && s[j] <= 'Z') j ++;
			string ss = s.substr (i, j-i); // 获取一个单词 
			
			if (enter) cout << endl; // 控制回车的输出 
			for (int r = 0;r < 7; r ++, cout << endl) { // 每个单词七行 
				int space = 0; // 控制空格的输出 
				for (int k = 0;k < ss.size();k ++) { // 每个字母 
					if (space) cout << ' ';
					for (int c = 0;c < 5;c ++) // 每个字母五行 
						cout << zimu[ss[k] - 'A'][r][c];
					space = 1;
				}	
			}
			enter = 1;
			i = j;
		}
	}

	return 0;
}

1110 区块反转 (25 分)

题解链接

你可能感兴趣的:(#,【PTA】,c++,算法)