持续更新中
1002 大整数的字符串存储
#include <iostream>
#include <string.h>
#include <vector>
using namespace std;
int main()
{
char n[100];
vector<string> v;
string num[10] = {"ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu"};
while (~scanf("%s", &n)) {
int sum = 0;
for (int i = 0; i < strlen(n); i++)
sum += n[i] - '0';
while (sum != 0) {
v.push_back(num[sum % 10].c_str());
sum /= 10;
}
for (int i = v.size() - 1; i >= 0 ; i--) {
printf("%s", v[i].c_str());
if(i == 0) printf("\n");
else printf(" ");
}
}
return 0;
}
1004 字符数组预留、结构体赋值
#include <iostream>
using namespace std;
struct Stu
{
char name[11];
char snum[11];
int grade;
} maxStu, minStu, tmpStu;
int main()
{
maxStu.grade = -1;
minStu.grade = 101;
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
scanf("%s%s%d", tmpStu.name, tmpStu.snum, &tmpStu.grade);
if (tmpStu.grade > maxStu.grade) maxStu = tmpStu;
if (tmpStu.grade < minStu.grade) minStu = tmpStu;
}
printf("%s %s\n", maxStu.name, maxStu.snum);
printf("%s %s\n", minStu.name, minStu.snum);
return 0;
}
1007 线性素数筛注意是否取上界
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100000;
bool isPrime[maxn];
int a[maxn];
int main() {
int n, j = 1, compsite;
memset(isPrime, true, sizeof(isPrime));
scanf("%d", &n);
for(int N = 2; N <= n; N++) {
if(isPrime[N]) a[j++] = N;
for(int i = 1; i < j; i++) {
if((compsite = a[i] * N) > n) break;
isPrime[compsite] = false;
if(N % a[i] == 0) break;
}
}
int cnt = 0;
for(int i = 2; i < j; i++)
if(a[i] - a[i - 1] == 2)
cnt++;
printf("%d", cnt);
return 0;
}
1008 循环移动数组的三种方法、最小公倍数
直接从 $\scriptsize a[N – M ]$ 开始循环输出,或使用辅助数组
# include <iostream>
using namespace std;
int main() {
int N, M, T, j;
scanf("%d%d", &N, &M);
int a[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 - M - 1; i++) printf("%d ", a[i]);
printf("%d", a[N - M - 1]);
return 0;
}
三次翻转法
环形替换法
1009 循环读入、逆序输出
注意自增在循环条件中时会多计算一次
#include <iostream>
using namespace std;
int main() {
char s[80][80];
int i = 0;
while(~scanf("%s", s[i])) i++;
for(int j = i - 1; j > 0; j--)
printf("%s ", s[j]);
printf("%s\n", s[0]);
return 0;
}
1012 注意交错为0,不同类型运算转换
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int main() {
int A[6];
memset(A, 0, sizeof(A));
int n, a, b = 0;
float num = 0;
scanf("%d", &n);
for(int i = 0; i < n; i++) {
scanf("%d", &a);
switch(a % 5) {
case 0: A[1] += a % 2 ? 0: a; break;
case 1: b = (b==1 ? -1: 1); A[2] += a*b; break;
case 2: A[3] ++; break;
case 3: A[4] += a; num++; break;
case 4: A[5] = A[5] > a ? A[5] : a; break;
}
}
if(A[1]) printf("%d ", A[1]); else printf("N ");
if(b) printf("%d ", A[2]); else printf("N ");
if(A[3]) printf("%d ", A[3]); else printf("N ");
if(A[4]) printf("%.1f ", A[4] / num); else printf("N ");
if(A[5]) printf("%d", A[5]); else printf("N");
return 0;
}
1013 线性素数筛、注意数组是否够容纳上界
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
const int maxn = 110000;
bool isPrime[maxn];
int a[10001];
int main()
{
int m, n, composite, count = 1, cnt = 1;
scanf("%d%d", &m, &n);
memset(isPrime, true, sizeof(isPrime));
for (int i = 2; cnt <= n; i++) {
if (isPrime[i]) a[cnt++] = i;
for (int j = 1; j < cnt; j++) {
if ((composite = a[j] * i) >= maxn) break;
isPrime[composite] = false;
if (i % a[j] == 0) break;
}
}
for (int i = m; i <= n; i++) {
if (count++ % 10 == 0 || i == n) printf("%d\n", a[i]);
else printf("%d ", a[i]);
}
return 0;
}
1014 指针遍历法、分段模拟、隐含输入限定
避免过多数组下标操作计算,防止计算繁复和频繁读写
复杂模拟尽量分段实现,避免耦合和代码难理解
注意隐含输入限制,星期范围、数字和字母、以及字母大小写
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
char day[7][4] = {"MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"};
char s0[61], s1[61], s2[61], s3[61];
int d = 0, h, m = 0;
scanf("%s%s%s%s", s0, s1, s2, s3);
while (s0[d] && s1[d]) {
if (s0[d] == s1[d] && s0[d] >= 'A' && s0[d] <= 'G')
break;
d++;
}
h = d + 1;
while (s0[h] && s1[h]) {
if (s0[h] == s1[h]) {
if (s0[h] >= 'A' && s0[h] <= 'N') {
h = s0[h] - 'A' + 10;
break;
}
else if (s0[h] >= '0' && s0[h] <= '9') {
h = s0[h] - '0';
break;
}
}
h++;
}
while (s2[m] && s3[m]) {
if (s2[m] == s3[m])
if (s2[m] >= 'a' && s2[m] <= 'z' || s2[m] >= 'A' && s2[m] <= 'Z')
break;
m++;
}
printf("%s %02d:%02d", day[s0[d] - 'A'], h, m);
return 0;
}
1017 竖式除法模拟、注意0处理
#include <iostream>
using namespace std;
int main()
{
char s[1001], *p = s;
int n, d = 0;
scanf("%s%d", s, &n);
for (int i = 0; s[i]; i++)
{
d = d * 10 + s[i] - '0';
s[i] = d / n + '0';
d %= n;
}
if(p[0] == '0' && p[1]) p++;
printf("%s %d", p, d);
return 0;
}
1019 sort用法
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int s[4], t[4];
int sNum, tNum;
scanf("%d", &tNum);
sNum = tNum;
while(true)
{
s[0] = sNum / 1000;
s[1] = sNum % 1000 / 100;
s[2] = sNum % 100 / 10;
s[3] = sNum % 10;
sort(s, s + 4);
for(int i = 0; i < 4; i++)
t[i] = s[3 - i];
tNum = t[3] + 10 * t[2] + 100 * t[1] + 1000 * t[0];
sNum = s[3] + 10 * s[2] + 100 * s[1] + 1000 * s[0];
printf("%04d - %04d = ", tNum, sNum);
if(tNum == sNum) { printf("%04d\n", 0); break; }
printf("%04d\n", tNum -= sNum);
if(tNum == 6174) break;
sNum = tNum;
}
return 0;
}
1022 进制转换除k取余法
#include <iostream>
#include <vector>
using namespace std;
int main() {
int a, b, d;
vector<int> v;
scanf("%d%d%d", &a, &b, &d);
a = a + b;
while(a != 0) {
v.push_back(a % d);
a /= d;
}
if(v.size())
for(int i = v.size() - 1; i >= 0; i--)
printf("%d", v[i]);
else printf("0");
return 0;
}
1023 边遍历边处理
更简洁的解法来自于 @OliverLew ,预先取0,并在之后的输入中检测一次性输出0,一边读入一边输出,O(1)内存有被惊艳到
#include <iostream>
using namespace std;
int main() {
int num[10], start = 10;
for (int i = 0; i < 10; i++) {
scanf("%d", &num[i]);
if(i < start && i && num[i])
start = i;
}
if(start == 10) printf("%d", 0);
else {
printf("%d", start);
num[start]--;
for(int i = 0; i < 10; i++)
while(num[i]--)
printf("%d", i);
}
return 0;
}
1027 输入格式、统一规律
下解给出倒三角和正三角分别输出情况
#include <iostream>
using namespace std;
int main() {
int n, i = 3, j = 1;
char c;
scanf("%d %c", &n, &c);
while(j + 2 * i <= n) {
j += 2 * i;
i += 2;
}
i -= 2;
int b = 0;
for(int k = i; k >= 1; k -= 2) {
int l = k, t = b++;
while(t--) putchar(' ');
while(l--) putchar(c);
putchar('\n');
}
b = i / 2 - 1;
for(int k = 3; k <= i; k += 2) {
int l = k, t = b--;
while(t--) putchar(' ');
while(l--) putchar(c);
putchar('\n');
}
printf("%d", n - j);
return 0;
}
更简便的办法是统一输出规律
#include <iostream>
#include <math.h>
using namespace std;
int main() {
int n; char c;
scanf("%d %c", &n, &c);
int medium = (int) sqrt((n + 1) / 2);
for(int row = 1; row <= 2 * medium - 1; row++) {
for(int i = 1; i <= medium - abs(row - medium) - 1; i++) putchar(' ');
for(int i = 1; i <= 2 * abs(row - medium) + 1; i++) putchar(c);
putchar('\n');
}
printf("%d", n - 2 * medium * medium + 1);
return 0;
}
1028 双重排序规则、读入特殊格式、简化思维
#include <iostream>
using namespace std;
struct Person {
char name[6];
int yy, mm, dd;
} maxP, minP, tmp, down, up;
// 转为时间戳比较或读入字符串strcmp更易
bool isAbove(Person &high, Person &low) {
if(high.yy != low.yy) return high.yy < low.yy;
if(high.mm != low.mm) return high.mm < low.mm;
return high.dd <= low.dd;
}
int main() {
int cnt, num = 0;
down.yy = 1814; down.mm = 9; down.dd = 6;
up.yy = 2014; up.mm = 9; up.dd = 6;
minP = down; maxP = up;
scanf("%d", &cnt);
for(int i = 0; i < cnt; i++) {
scanf("%s%d/%d/%d", tmp.name, &tmp.yy, &tmp.mm, &tmp.dd);
if(isAbove(down, tmp) && isAbove(tmp, up)) {
if(isAbove(tmp, maxP)) maxP = tmp;
if(isAbove(minP, tmp)) minP = tmp;
num++;
}
}
if(num) printf("%d %s %s", num, maxP.name, minP.name);
else printf("0");
return 0;
}
1029 散列思想、统一形式、大小写转换
#include <iostream>
using namespace std;
int main()
{
char s0[10000], s1[10000], *p = s1, c;
bool map[256] = {0};
scanf("%s%s", s0, s1);
while (c = *p) {
if(*p >= 'a' && *p <= 'z')
c = *p - 32;
map[c] = true;
p++;
}
p = s0;
while (c = *p) {
if(*p >= 'a' && *p <= 'z')
c = *p - 32;
if (!map[c]) {
putchar(c);
map[c] = true;
}
p++;
}
return 0;
}
1032 结果保存和最值
#include <iostream>
using namespace std;
int main() {
int n, t, maxN, maxP = -1;
scanf("%d\n", &n);
int p[n + 1] = {0};
while(~scanf("%d %d", &n, &t)) {
p[n] += t;
if(p[n] > maxP) {
maxP = p[n];
maxN = n;
}
}
printf("%d %d", maxN, maxP);
return 0;
}
1033 散列思想、统一形式
#include <iostream>
using namespace std;
int main(){
int map[256] = {0};
char c, t;
while((c = getchar()) != '\n') {
if(c >= 'a' && c <= 'z')
c -= 32;
map[c]++;
}
while((c = getchar()) != '\n') {
if(map['+'] && c >= 'A' && c <= 'Z')
continue;
t = c;
if(c >= 'a' && c <= 'z')
t = c - 32;
if(!map[t]) putchar(c);
}
return 0;
}
1037 类进制计算、负数模运算为负结果、注意0
#include <iostream>
using namespace std;
int main()
{
int g0, s0, k0;
int g1, s1, k1;
scanf("%d.%d.%d", &g0, &s0, &k0);
scanf("%d.%d.%d", &g1, &s1, &k1);
long t0 = k0 + s0 * 29 + g0 * 493;
long t1 = k1 + s1 * 29 + g1 * 493;
if(t1 >= t0) printf("%d.%d.%d", (t1 - t0) / 493, (t1 - t0) % 493 / 29, (t1 - t0) % 29);
else printf("-%d.%d.%d", (t0 - t1) / 493, (t0 - t1) % 493 / 29, (t0 - t1) % 29);
return 0;
}
1038 注意数组初始化
#include <iostream>
using namespace std;
int main()
{
int N, K, p;
scanf("%d", &N);
int a[101] = {0};
for (int i = 0; i < N; i++) {
scanf("%d", &p);
a[p]++;
}
scanf("%d", &K);
while (--K) {
scanf("%d", &p);
printf("%d ", a[p]);
}
scanf("%d", &p);
printf("%d", a[p]);
return 0;
}
1039 类桶排思想、输出带符号格式
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int main()
{
int pearl[256], less = 0, more = 0;
char c;
memset(pearl, 0, sizeof(pearl));
while ((c = getchar()) != '\n')
pearl[c]++;
while ((c = getchar()) != '\n')
pearl[c]--;
for (int i = 0; i < 256; i++) {
if (pearl[i] < 0) less -= pearl[i];
else if (pearl[i] > 0) more += pearl[i];
}
if (less) printf("No %d", less);
else printf("Yes %d", more);
return 0;
}
1042 最值、双重排序规则
#include <iostream>
using namespace std;
int main()
{
char c;
int max = 25;
int num[26] = {0};
while ((c = getchar()) != '\n')
{
if (c >= 'a' && c <= 'z')
num[c - 'a']++;
else if (c >= 'A' && c <= 'Z')
num[c - 'A']++;
}
for (int i = 24; i >= 0; i--)
if (num[i] >= num[max])
max = i;
printf("%c %d", max + 'a', num[max]);
return 0;
}
1048 双指针、char运算转int、统一0
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
char a[101], b[101];
scanf("%s%s", a, b);
int i, j, cnt = 1;
i = strlen(a) - 1;
j = strlen(b) - 1;
cnt = max(i, j);
a[cnt + 1] = '\0';
int A, B, tmp, flag = 1;
while (cnt >= 0) {
// 或用平移方法,通过下标映射来对齐运算
A = i < 0 ? 0 : a[i] - '0';
B = j < 0 ? 0 : b[j] - '0';
if (flag) {
tmp = (A + B) % 13;
if (tmp == 10) a[cnt] = 'J';
else if (tmp == 11) a[cnt] = 'Q';
else if (tmp == 12) a[cnt] = 'K';
else a[cnt] = tmp + '0';
}
else {
tmp = B - A;
if (tmp < 0) a[cnt] = tmp + 10 + '0';
else a[cnt] = tmp + '0';
}
cnt--;
flag = !flag;
if (i != -1) i--;
if (j != -1) j--;
}
printf("%s\n", a);
return 0;
}
1049 int溢出、double不精确、数字规律
枚举会超时,故寻找数字规律
循环体核心语句num必须置前且为较大的类型,否则先算i * (N – i + 1)可能会导致int溢出
IEEE754的double只是近似值,为达到可用精度,先挪动小数点计算后再恢复小数点
注意强制转型是就近结合的,double转long long时整体运算转型需要加括号以防止精度丢失
参考 @zhengrh
#include <iostream>
using namespace std;
int main()
{
int N;
double num;
long long sum = 0;
scanf("%d", &N);
for (int i = 1; i <= N; i++) {
scanf("%lf", &num);
sum += (long long) (num * 1000) * i * (N - i + 1);
}
printf("%.2f", sum / 1000.0);
return 0;
}
1052 特殊字符读取、转义、正则读取
这道题有够坑的,if条件之多也是目前之最了,此处参考 @OliverLew 源码
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int main() {
char c, symbol[3][10][5];
memset(symbol, '\0', sizeof(symbol));
for(int i = 0; i < 3; i++)
for(int j = 0; (c = getchar()) != '\n'; j)
if(c == '[') scanf("%[^]]", symbol[i][j++]);
int n, index[5];
scanf("%d", &n);
while(n--)
{
for(int i = 0; i < 5; i++)
scanf("%d", &index[i]);
if (index[0] > 0 && index[0] <= 10 && *symbol[0][--index[0]]
&& index[1] > 0 && index[1] <= 10 && *symbol[1][--index[1]]
&& index[2] > 0 && index[2] <= 10 && *symbol[2][--index[2]]
&& index[3] > 0 && index[3] <= 10 && *symbol[1][--index[3]]
&& index[4] > 0 && index[4] <= 10 && *symbol[0][--index[4]])
printf("%s(%s%s%s)%s\n",symbol[0][index[0]],symbol[1][index[1]],symbol[2][index[2]],symbol[1][index[3]],symbol[0][index[4]]);
else printf("Are you kidding me? @\\/@\n");
}
return 0;
}
1082 思维转换取值大的反而小
#include <iostream>
using namespace std;
int main() {
while(getchar() != '\n');
int mx = -1, mn = 10001, mxN, mnN, x, y, pos, t;
while(~scanf("%d%d%d", &t, &x, &y)) {
pos = x * x + y * y;
if(pos > mx) { mxN = t; mx = pos; }
if(pos < mn) { mnN = t; mn = pos; }
}
printf("%04d %04d", mnN, mxN);
return 0;
}
1088 注意变量可能为double型
#include <iostream>
using namespace std;
int main() {
int M, X, Y, a, b;
double c;
scanf("%d%d%d", &M, &X, &Y);
for(int a = 99; a >= 10; a--) {
b = a % 10 * 10 + a / 10;
if(a > b) c = (a - b) * 1.0 / X;
else c = (b - a) * 1.0 / X;
if(b == Y * c) {
printf("%d", a);
printf(M > a ? " Gai": (M < a ? " Cong": " Ping"));
printf(M > b ? " Gai": (M < b ? " Cong": " Ping"));
printf(M > c ? " Gai": (M < c ? " Cong": " Ping"));
return 0;
}
}
printf("No Solution");
return 0;
}
1089 暴力枚举
知道是暴力枚举有什么用,还不是被打败了没模拟出来…下次再来
1092 结构体数组初始化和排序、循环边界
可以不排序,一次遍历记录最大值序号,一次遍历输出所有最大值序号
#include <iostream>
#include <algorithm>
using namespace std;
struct B{
int type;
int sell;
};
bool cmp (B b1, B b2) {
if(b1.sell != b2.sell) return b1.sell > b2.sell;
return b1.type < b2.type;
}
int main() {
int N, M, T;
scanf("%d%d", &N, &M);
B Ins[N] = {0};
while(M--) {
for(int i = 0; i < N; i++) {
scanf("%d", &T);
Ins[i].type = i + 1;
Ins[i].sell += T;
}
}
sort(Ins, Ins + N, cmp);
T = Ins[0].sell;
printf("%d\n", T);
printf("%d", Ins[0].type);
for(int i = 0; i < N - 1 && Ins[i + 1].sell == T; i++)
printf(" %d", Ins[i + 1].type);
return 0;
}
1093 getchar != EOF读入换行也会停止
#include <iostream>
using namespace std;
int main() {
bool isExist[128] = {0};
char c;
int i = 2;
while(i) {
while((c = getchar()) != '\n') {
if(!isExist[c]) {
isExist[c] = true;
putchar(c);
}
}
i--;
}
return 0;
}
1094 注意已给定长度,字符串转整数
字符串转整数库函数
#include <stdlib.h> #include <stdio.h> int atoi(const char *nptr);
复制指定地址开始指定个数字符到字符数组库函数
#include <stdio.h> char *strncpy(char *dest, const char *src, int n)
#include <iostream>
using namespace std;
bool isPrime(long long n) {
if(n <= 1) return false;
for(long long i = 2; i * i <= n; i++)
if(n % i == 0) return false;
return true;
}
long long toNum(char *p, int i) {
long long e = 1;
long long sum = 0;
for(; i >= 0; i--) {
sum += (*(p + i) - '0') * e;
e *= 10;
}
return sum;
}
int main() {
int n, k;
char s[1000], *p = s;
scanf("%d %d", &n, &k);
scanf("%s", s);
k--;
while(*p) {
long long num = toNum(p, k);
if(isPrime(num)) {
for(int i = 0; i <= k; i++)
printf("%c", *(p + i));
return 0;
}
p++;
}
printf("404");
return 0;
}