题目链接:http://pat.zju.edu.cn/contests/pat-b-practise
注:这里涵盖了PAT BASIC的全部30道题,难度较易,但还是为初学者做一个参考,最好自己想出思路,找出错误数据,代码仅供参考。
1001 注意统计砍一半的次数
#include
#include
using namespace std;
int n;
void solve() {
int cnt = 0;
while(n != 1) {
if(n & 1) n = (3*n+1)>>1;
else n >>= 1;
cnt++;
}
printf("%d\n", cnt);
}
int main() {
while(~scanf("%d", &n)) {
solve();
}
}
1002 不解释
#include
#include
#include
using namespace std;
char s[1010];
string dig[] = {"ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu"};
void solve() {
int i = 0, sum = 0;
while(s[i] != '\0') {
sum += s[i]-'0';
i++;
}
stack stk;
while(sum) {
stk.push(sum%10);
sum /= 10;
}
while(stk.size() > 1) {
cout << dig[stk.top()] << " ";
stk.pop();
}
cout << dig[stk.top()] << endl;
stk.pop();
}
int main() {
while(~scanf("%s", s))
solve();
return 0;
}
1003 我要通过
有几点注意:
1:不能有除P、A、T外其他字符,且P和T只能出现一次,且P在T左边
2:说白了就是判断(P左边A的个数)*(P与T之间A的个数)是否等于(T右边A的个数)。
#include
#include
#include
using namespace std;
int main() {
int t;
char s[110];
scanf("%d", &t);
while(t--) {
scanf("%s", s);
bool flag = true;
int n = strlen(s);
int pp = -1, pt = -1;
for(int i = 0; i < n; i++) {
if(s[i] != 'P' && s[i] != 'A' && s[i] != 'T') { flag = false; break;}
if(s[i] == 'P') {
if(pp == -1) pp = i;
else {flag = false; break; }
}
if(s[i] == 'T') {
if(pt == -1) pt = i;
else {flag = false; break; }
}
}
if(!flag || pt - pp < 2) { printf("NO\n"); continue; }
if((pp*(pt-pp-1) == n-pt-1)) printf("YES\n");
else printf("NO\n");
}
return 0;
}
1004 不解释
#include
#include
#include
using namespace std;
int main() {
int n, grade[1010];
string name[1010], id[1010];
while(cin >> n) {
int maxg = 0, ming = 101, id1 = 0, id2 = 0;
for(int i = 0; i < n; i++) {
cin >> name[i] >> id[i] >> grade[i];
if(maxg < grade[i]) { id1 = i; maxg = grade[i]; }
if(ming > grade[i]) { id2 = i; ming = grade[i]; }
}
cout << name[id1] << " " << id[id1] << endl;
cout << name[id2] << " " << id[id2] << endl;
}
return 0;
}
1005 继续3n+1猜想
数字有3中状态:0未使用,1使用但为被覆盖,2使用且被覆盖。那么重要的就是标记过程了,具体见代码。
#include
#include
#include
#include
using namespace std;
int n, a[110], vis[110], key[110];
bool cmp(int a, int b) {
return a > b;
}
void solve() {
for(int i = 0; i < n; i++) {
long long m = a[i];
if(vis[m] == 2) continue;
while(m != 1) {
if(m & 1) m = (m*3+1)>>1;
else m >>= 1;
if(m > 100) continue;
if(vis[m] == 2) break;
if(vis[m] == 1) vis[m] = 2;
}
}
int cnt = 0;
for(int i = 0; i <= 100; i++)
if(vis[i] == 1) key[cnt++] = i;
sort(key, key+cnt, cmp);
for(int i = 0; i < cnt-1; i++)
printf("%d ", key[i]);
printf("%d\n", key[cnt-1]);
}
int main() {
while(~scanf("%d", &n)) {
memset(vis, 0, sizeof(vis));
for(int i = 0; i < n; i++) {
scanf("%d", &a[i]);
vis[a[i]] = 1;
}
solve();
}
return 0;
}
1006 不解释
#include
#include
using namespace std;
int main() {
int dig[3], n;
while(~scanf("%d", &n)) {
dig[0] = dig[1] = dig[2] = 0;
int i = 0;
while(n != 0) {
dig[i++] = n%10;
n /= 10;
}
if(dig[2] != 0) for(int i = 0; i < dig[2]; i++) printf("B");
if(dig[1] != 0) for(int i = 0; i < dig[1]; i++) printf("S");
if(dig[0] != 0) for(int i = 1; i <= dig[0]; i++) printf("%d", i);
printf("\n");
}
}
1007 用筛法把100000以内素数都求出来
#include
#include
using namespace std;
const int MAX_N = 100010;
int prime[MAX_N];
bool is_prime[MAX_N+1];
int cnt = 0, n;
void GetPrime() {
for(int i = 0; i <= MAX_N; i++) is_prime[i] = true;
is_prime[0] = is_prime[1] = false;
for(int i = 2; i <= MAX_N; i++)
if(is_prime[i]) {
prime[cnt++] = i;
for(int j = 2*i; j <= MAX_N; j += i)
is_prime[j] = false;
}
}
void solve() {
int res = 0;
for(int i = 1; i < cnt && prime[i] <= n; i++)
if(prime[i]-prime[i-1] == 2) res++;
printf("%d\n", res);
}
int main() {
GetPrime();
while(~scanf("%d", &n))
solve();
return 0;
}
1008 不解释
#include
#include
using namespace std;
int main() {
int n, m, a[110];
while(~scanf("%d%d", &n, &m)) {
m %= n;
for(int i = 0; i < n; i++) scanf("%d", &a[i]);
for(int i = n-m; i < n; i++) printf("%d ", a[i]);
for(int i = 0; i < n-1-m; i++) printf("%d ", a[i]);
printf("%d\n", a[n-1-m]);
}
return 0;
}
1009 不解释
#include
#include
#include
using namespace std;
int main() {
string str[100];
int n = 0;
while(cin >> str[n++]) ;
for(int i = n-2; i > 0; i--)
cout << str[i] << " ";
cout << str[0] << endl;
return 0;
}
1010 注意最后求得导数为0 的情况
#include
#include
using namespace std;
int main() {
//freopen("in.txt", "r", stdin);
bool flag = true;
int a[1010], b[1010];
int n = 0;
while(~scanf("%d", &a[n++])) ;
int cnt = 0;
for(int i = 0; i < n; i += 2)
if(a[i] != 0 && a[i+1] != 0 ) {
b[cnt++] = a[i]*a[i+1];
b[cnt++] = a[i+1]-1;
}
if(cnt == 0) printf("0 0\n");
else {
for(int i = 0; i < cnt-1; i++) printf("%d ", b[i]);
printf("%d\n", b[cnt-1]);
}
return 0;
}
1011 long long就可以过
#include
#include
using namespace std;
int main() {
int t;
long long a, b, c;
scanf("%d", &t);
for(int cas = 1; cas <= t; cas++) {
scanf("%lld%lld%lld", &a, &b, &c);
printf("Case #%d: ", cas);
if(a+b > c) printf("true\n");
else printf("false\n");
}
return 0;
}
1012 注意每种数字个数为0的表示情况
#include
#include
#include
using namespace std;
int main() {
//freopen("in.txt", "r", stdin);
int A1, A2, A3, A5, c2, c4, c5, x, N;
float A4;
while(~scanf("%d", &N)) {
int flag = 1;
A1 = A2 = A3 = A5 = c2 = c4 = c5 = 0;
A4 = 0;
while(N--) {
scanf("%d", &x);
if(x % 5 == 0) { if(x % 2 == 0) A1 += x; }
else if(x % 5 == 1) { A2 += flag*x; flag = -flag; c2++; }
else if(x % 5 == 2) A3++;
else if(x % 5 == 3) {A4 += x; c4++; }
else if(x % 5 == 4) { if(A5 < x) A5 = x; c5++; }
}
if(A1 == 0) printf("N ");
else printf("%d ", A1);
if(c2 == 0) printf("N ");
else printf("%d ", A2);
if(A3 == 0) printf("N ");
else printf("%d ", A3);
if(c4 == 0) printf("N ");
else printf("%.1f ", A4/c4);
if(c5 == 0) printf("N\n");
else printf("%d\n", A5);
}
return 0;
}
1013 范围太大,依然用筛法,时间上有保证,但注意边界
#include
#include
using namespace std;
int prime[10010], n = 1;
bool is_prime[105000];
void GetPrime() {
for(int i = 0; i <= 105000; i++) is_prime[i] = true;
is_prime[0] = is_prime[1] = false;
for(int i = 2; i <= 105000; i++)
if(is_prime[i]) {
prime[n++] = i;
for(int j = 2*i; j <= 105000; j += i)
is_prime[j] = false;
}
}
int main() {
int N, M;
GetPrime();
while(~scanf("%d%d", &N, &M)) {
int cnt = 0;
for(int i = prime[N]; i <= prime[M]; i++) {
if(is_prime[i]) {
if(cnt == 0) { printf("%d", i); cnt++; }
else if(cnt < 9) { printf(" %d", i); cnt++; }
else { printf(" %d\n", i); cnt = 0; }
}
}
if((M-N+1)%10 != 0) printf("\n");
}
return 0;
}
1014 注意顺序,还能不能好好的约会了!!!
#include
#include
#include
using namespace std;
char DAY[8][4] = {"MON","TUE","WED","THU","FRI","SAT","SUN"};
int main() {
char s1[66], s2[66], s3[66], s4[66];
int day, hour, minute;
while(~scanf("%s%s%s%s", s1, s2, s3, s4)) {
int id = 0;
for(int i = 0; s1[i] != '\0'; i++)
if(s1[i] == s2[i] && s1[i] >= 'A' && s1[i] <= 'G') { day = s1[i]-'A'; id = i; break; }
for(int i = id+1; s1[i] != '\0'; i++)
if(s1[i] == s2[i]) {
if(s1[i] >= 'A' && s1[i] <= 'N') { hour = s1[i]-'A'+10; break; }
else if(s1[i] >= '0' && s1[i] <= '9') { hour = s1[i]-'0'; break; }
}
for(int i = 0; s3[i] != '\0'; i++)
if(s3[i] == s4[i] && isalpha(s3[i])) { minute = i; break; }
printf("%s %02d:%02d\n", DAY[day], hour, minute);
}
return 0;
}
1015 分开成4种人,逐个进行排序
#include
#include
#include
#include
using namespace std;
struct node {
int id, df, cf;
bool operator < (const node& rhs) const {
if(df+cf != rhs.df+rhs.cf) return df+cf > rhs.df+rhs.cf;
if(df != rhs.df) return df > rhs.df;
return id < rhs.id;
}
};
vector one, two, thr, four;
int N, L, H;
int main() {
int id, cf, df, c1, c2, c3, c4;
while(~scanf("%d%d%d", &N, &L, &H)) {
one.clear(); two.clear(); thr.clear(); four.clear();
while(N--) {
scanf("%d%d%d", &id, &df, &cf);
if(df < L || cf < L) continue;
if(cf >= H && df >= H) one.push_back((node){id, df, cf});
else if(cf < H && df >= H) two.push_back((node){id, df, cf});
else if(cf < H && df < H && df >= cf) thr.push_back((node){id, df, cf});
else four.push_back((node){id, df, cf});
}
sort(one.begin(), one.end());
sort(two.begin(), two.end());
sort(thr.begin(), thr.end());
sort(four.begin(), four.end());
c1 = one.size(); c2 = two.size(); c3 = thr.size(); c4 = four.size();
printf("%d\n", c1+c2+c3+c4);
for(int i = 0; i < c1; i++)
printf("%d %d %d\n", one[i].id, one[i].df, one[i].cf);
for(int i = 0; i < c2; i++)
printf("%d %d %d\n", two[i].id, two[i].df, two[i].cf);
for(int i = 0; i < c3; i++)
printf("%d %d %d\n", thr[i].id, thr[i].df, thr[i].cf);
for(int i = 0; i < c4; i++)
printf("%d %d %d\n", four[i].id, four[i].df, four[i].cf);
}
}
1016 不解释
#include
#include
using namespace std;
int main() {
int a, b, da, db;
while(~scanf("%d%d%d%d", &a, &da, &b, &db)) {
int ca = 0, cb = 0;
while(a != 0) {
if(da == a%10) ca++;
a /= 10;
}
while(b != 0) {
if(db == b%10) cb++;
b /= 10;
}
int pa = 0, pb = 0;
int x = 1;
while(ca--) {
pa += da*x;
x *= 10;
}
x = 1;
while(cb--) {
pb += db*x;
x *= 10;
}
printf("%d\n", pa+pb);
}
return 0;
}
1017 手算怎么算,你就怎么算,注意商为0
#include
#include
using namespace std;
int main() {
char s[1010];
int n, b, a[1010], q[1010];
while(~scanf("%s%d", s, &b)) {
for(n = 0; s[n] != '\0'; n++) a[n] = s[n]-'0';
if(n == 1 && a[0] < b) { printf("0 %d\n", a[0]); continue; }
q[1] = 0;
for(int i = 0; i < n-1; i++) {
q[i] = a[i]/b;
a[i+1] += a[i]%b*10;
}
q[n-1] = a[n-1]/b;
if(q[0] != 0) printf("%d", q[0]);
for(int i = 1; i < n; i++) printf("%d", q[i]);
printf(" %d\n", a[n-1]%b);
}
return 0;
}
1018 不解释
#include
#include
using namespace std;
int judge(char x, char y) {
if(x == y) return 1;
if((x == 'C' && y == 'J') || (x == 'J' && y == 'B') || (x == 'B' && y == 'C')) return 0;
return 2;
}
int main() {
//freopen("in.txt", "r", stdin);
int N, JS, JP, J[3], Y[3];
char JIA, YI;
while(~scanf("%d", &N, &JIA)) {
JS = JP = J[0] = J[1] = J[2] = Y[0] = Y[1] = Y[2] = 0;
for(int i = 0; i < N; i++) {
scanf("\n%c %c", &JIA, &YI);
int ans = judge(JIA, YI);
if(ans == 0) {
JS++;
if(JIA == 'C') J[1]++;
else if(JIA == 'J') J[0]++;
else if(JIA == 'B') J[2]++;
}
else if(ans == 1) { JP++; }
else {
if(YI == 'C') Y[1]++;
else if(YI == 'J') Y[0]++;
else if(YI == 'B') Y[2]++;
}
}
printf("%d %d %d\n%d %d %d\n", JS, JP, N-JS-JP, N-JS-JP, JP, JS);
int maxj = 0, maxy = 0, idj, idy;
for(int i = 0; i < 3; i++) {
if(maxj <= J[i]) { maxj = J[i]; idj = i; }
if(maxy <= Y[i]) { maxy = Y[i]; idy = i; }
}
if(idj == 0) printf("J ");
else if(idj == 1) printf("C ");
else if(idj == 2) printf("B ");
if(idy == 0) printf("J\n");
else if(idy == 1) printf("C\n");
else if(idy == 2) printf("B\n");
}
return 0;
}
1019 注意一开始输入就是6174的情况
#include
#include
#include
using namespace std;
void getnum(int& x, int& a, int& b) {
int num[5], n = 0;
num[0] = num[1] = num[2] = num[3] = 0;
while(x != 0) {
num[n++] = x%10;
x /= 10;
}
sort(num, num+4);
a = num[3]*1000+num[2]*100+num[1]*10+num[0];
b = num[0]*1000+num[1]*100+num[2]*10+num[3];
x = a - b;
}
int main() {
int a, b, x;
while(~scanf("%d", &x)) {
while(1) {
getnum(x, a, b);
printf("%04d - %04d = %04d\n", a, b, x);
if(x == 0 || x == 6174) break;
}
}
return 0;
}
1020 月饼单价排序
#include
#include
#include
using namespace std;
struct node {
double sto, sell, price;
bool operator < (const node& rhs) const {
return price > rhs.price;
}
}MK[1010];
int N, D;
int main() {
while(~scanf("%d%d", &N, &D)) {
for(int i = 0; i < N; i++) scanf("%lf", &MK[i].sto);
for(int i = 0; i < N; i++) scanf("%lf", &MK[i].sell);
for(int i = 0; i < N; i++) MK[i].price = MK[i].sell/MK[i].sto;
sort(MK, MK+N);
double res = 0;
for(int i = 0; i < N; i++) {
if(D <= MK[i].sto) { res += MK[i].price*D; break; }
res += MK[i].sell;
D -= MK[i].sto;
}
printf("%.2lf\n", res);
}
return 0;
}
1021 不解释
#include
#include
#include
using namespace std;
int main() {
char s[1010], num[11];
while(~scanf("%s", s)) {
memset(num, 0, sizeof(num));
for(int i = 0; s[i] != '\0'; i++) num[s[i]-'0']++;
for(int i = 0; i < 10; i++)
if(num[i] != 0) printf("%d:%d\n", i, num[i]);
}
return 0;
}
1022 进制转换
#include
#include
using namespace std;
int main() {
int dig[50], n, a, b, d;
while(~scanf("%d%d%d", &a, &b, &d)) {
int c = a+b;
if(c == 0) { printf("0\n"); continue; }
n = 0;
while(c != 0) {
dig[n++] = c%d;
c /= d;
}
for(int i = n-1; i >= 0; i--)
printf("%d", dig[i]);
printf("\n");
}
return 0;
}
1023 先取个非0最小数,再把所有0跟上,然后其他所有数从小到大排。
#include
#include
#include
using namespace std;
int main() {
int num[11];
while(~scanf("%d", &num[0])) {
for(int i = 1; i <= 9; i++) scanf("%d", &num[i]);
int id = 0;
for(int i = 1; i <= 9; i++) if(num[i] != 0) { id = i; break; }
printf("%d", id); num[id]--;
while(num[0]--) cout << "0";
for(int i = 1; i <= 9; i++) {
while(num[i]--) cout << i;
}
cout << endl;
}
return 0;
}
1024 科学计数法
指数为正式,主要问题在于判断小数点最后变到了哪里。
指数为负时,主要问题在于前面加上几个0。
有很多细节要注意。
#include
#include
#include
using namespace std;
char s[10010];
int main() {
//freopen("in.txt", "r", stdin);
while(~scanf("%s", s)) {
if(s[0] == '-') printf("-");
int e = 4;
while(s[e] != 'E') e++;
int id = e+2, p2 = 0;
while(s[id] != '\0') { p2 = 10*p2+s[id]-'0'; id++; }
if(s[e+1] == '+') {
printf("%c", s[1]);
id = p2+2;
if(id < e) {
for(int i = 3; i <= id; i++) printf("%c", s[i]);
if(id != e-1) printf(".");
for(int i = id+1; i < e; i++) printf("%c", s[i]);
} else {
for(int i = 3; i < e; i++) printf("%c", s[i]);
for(int i = e; i <= id; i++) printf("0");
}
} else {
if(p2 == 0){
printf("%c.", s[1]);
} else {
printf("0.");
for(int i = 1; i < p2; i++) printf("0");
printf("%c", s[1]);
}
for(int i = 3; i < e; i++) printf("%c", s[i]);
}
printf("\n");
}
return 0;
}
1025 反转链表
用数组做可以不用反转直接输出来,但是判断每段首尾挺麻烦,用STL的reverse实在方便。
#include
#include
#include
#include
using namespace std;
typedef pair P;
P coll[100010];
struct node {
int addr, data, next;
};
vector LK;
int main() {
int n, k, head, addr, data, next;
while(~scanf("%d%d%d", &head, &n, &k)) {
LK.clear();
for(int i = 0; i < n; i++) {
scanf("%d%d%d", &addr, &data, &next);
P p;
p.first = data; p.second = next;
coll[addr] = p;
}
int cnt = 0, index = head;
while(index != -1) {
LK.push_back((node){index, coll[index].first, coll[index].second});
index = coll[index].second;
cnt++;
}
int t = cnt/k;
for(int i = 0; i < t; i++)
reverse(LK.begin()+i*k, LK.begin()+(i+1)*k);
t = LK.size();
for(int i = 0; i < t-1; i++)
printf("%05d %d %05d\n", LK[i].addr, LK[i].data, LK[i+1].addr);
printf("%05d %d -1\n", LK[t-1].addr, LK[t-1].data);
}
return 0;
}
1026 注意秒要四舍五入
#include
#include
using namespace std;
int main() {
int C1, C2;
while(~scanf("%d%d", &C1, &C2)) {
int second = 1.0*(C2-C1)/100+0.5;
int hour = second/3600;
second %= 3600;
int minute = second/60;
second %= 60;
printf("%02d:%02d:%02d\n", hour, minute, second);
}
return 0;
}
1027 算了,也不解释了
#include
#include
#include
using namespace std;
int main() {
int n;
char c;
while(~scanf("%d %c", &n, &c)) {
int x = sqrt(2.0*(n+1))-1;
if(x % 2 == 0) x--;
for(int i = x; i >= 1; i -= 2) {
for(int j = 0; j < (x-i)/2; j++)
printf(" ");
for(int j = 0; j < i; j++)
printf("%c", c);
printf("\n");
}
for(int i = 3; i <= x; i += 2) {
for(int j = 0; j < (x-i)/2; j++)
printf(" ");
for(int j = 0; j < i; j++)
printf("%c", c);
printf("\n");
}
printf("%d\n", n-(x+1)*(x+1)/2+1);
}
return 0;
}
1028 时间比较,注意重载比较运算符,边界问题注意
#include
#include
#include
#include
using namespace std;
struct date {
int year, month, day;
bool operator > (const date& rhs) const {
if(year != rhs.year) return year > rhs.year;
if(month != rhs.month) return month > rhs.month;
return day > rhs.day;
}
bool operator >= (const date& rhs) const {
if(year != rhs.year) return year > rhs.year;
if(month != rhs.month) return month > rhs.month;
return day >= rhs.day;
}
};
vector name, bir;
int main() {
int n;
while(cin >> n) {
date mind, maxd, tmp, dlow, dhigh;
string nm, br;
maxd.year = 1814; maxd.month = 9; maxd.day = 6;
mind.year = 2014; mind.month = 9; mind.day = 6;
dlow = maxd; dhigh = mind;
int id1 = 0, id2 = 0, cnt = 0;
name.clear(); bir.clear();
for(int i = 0; i < n; i++) {
cin >> nm >> br;
name.push_back(nm);
bir.push_back(br);
tmp.year = (br[0]-'0')*1000+(br[1]-'0')*100+(br[2]-'0')*10+br[3]-'0';
tmp.month = (br[5]-'0')*10+br[6]-'0';
tmp.day = (br[8]-'0')*10+br[9]-'0';
if(tmp > dhigh || dlow > tmp) continue;
if(mind >= tmp) { mind = tmp; id1 = i; }
if(tmp >= maxd) { maxd = tmp; id2 = i; }
cnt++;
}
if(cnt > 0)
cout << cnt << " " << name[id1] << " " << name[id2] << endl;
else
cout << "0" << endl;
}
return 0;
}
1029 字符串细节
#include
#include
#include
#include
using namespace std;
char s1[82], s2[82];
bool alpha[27], dig[12], space;
int main() {
while(~scanf("%s", s1)) {
scanf("%s", s2);
memset(alpha, false, sizeof(alpha));
memset(dig, false, sizeof(dig));
space = false;
for(int i = 0; s2[i] != '\0'; i++) {
if(isdigit(s2[i])) {
dig[s2[i]-'0'] = true;
} else if(isalpha(s2[i])) {
if(s2[i]>='a' && s2[i]<='z') s2[i] += 'A'-'a';
alpha[s2[i]-'A'] = true;
} else if(s2[i] == '_') space = true;
}
for(int i = 0; s1[i] != '\0'; i++) {
if(isdigit(s1[i])) {
if(!dig[s1[i]-'0']) { printf("%c", s1[i]); dig[s1[i]-'0'] = true; }
} else if(isalpha(s1[i])) {
if(s1[i]>='a' && s1[i]<='z') s1[i] += 'A'-'a';
if(!alpha[s1[i]-'A']) { printf("%c", s1[i]); alpha[s1[i]-'A'] = true; }
} else if(s1[i] == '_') {
if(!space) { printf("_"); space = true; }
}
}
printf("\n");
}
return 0;
}
1030 排序,将不可以的一个个排除
#include
#include
#include
using namespace std;
int n, p;
long long a[100010];
int main() {
while(~scanf("%d%d", &n, &p)) {
for(int i = 0; i < n; i++)
scanf("%lld", &a[i]);
sort(a, a+n);
int ans = 0, j = 0;
long long tmp = a[0]*p;
for(int i = 0; i < n; i++) {
while(j < i && tmp < a[i]) tmp = a[++j]*p;
if(ans < i-j+1) ans = i-j+1;
}
printf("%d\n", ans);
}
return 0;
}