1、
数位分离的应用
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int main()
{
int sum = 0;
for (int i = 1 ;i <= 2020 ;i ++)
{
int j = i;
while (j)
{
int x = j % 10;
if (x == 2) sum ++;
j /= 10;
}
}
cout << sum;
return 0;
}
2、
欧几里得算法的应用
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int gcd(int a ,int b)
{
return b ? gcd(b ,a % b) : a;
}
int main()
{
int ans = 0;
for (int i = 1 ;i <= 2020 ;i ++)
for (int j = 1 ;j <= 2020 ;j ++) if (gcd(i ,j) == 1) ans ++;
cout << ans;
return 0;
}
3、
读完题后先不要急着暴力破解,我们观察可以发现题目所求的20行20列是这个图的对角线数据,而对角线数据是有规律的:1 ,1 + 4 , 1 + 4 + 8 ,1 + 4 + 8 +12 .。。。
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
int ans = 1 ,cnt = 4;
for (int i = 1 ;i < 20 ;i ++)
{
ans += cnt;
cnt += 4;
}
cout << ans;
return 0;
}
4、
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int m[13] = {0 ,31 ,28 ,31 ,30 ,31 ,30 ,31 ,31 ,30 ,31 ,30 ,31};//每个月对应的天数
int main()
{
int st = 6 ,sum = 0;
for (int i = 2000 ;i <= 2020 ;i ++)//遍历年份
{
int flag = 0;
if (i % 400 == 0 || (i % 100 != 0 && i % 4 == 0)) flag = 1;//如果是闰年,二月加一天
for (int j = 1 ;j <= 12 ; j ++)//遍历月份
{
int month = m[j];
if (j == 2) month += flag;
for (int d = 1 ;d <= month ;d ++)//遍历日
{
if (d == 1 || st == 1) sum += 2;
else
sum += 1;
st ++;
if (st > 7) st = 1;
if (i == 2020 && j == 10 && d == 1)
{
cout << sum;
return 0;
}
}
}
}
return 0;
}
5、
这个题目我个人感觉有点难,倒不是思路的复杂,而是不容易想到如何对题目进行抽象转化。本题的思路就是并查集加dfs。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define N 100
int f[N][N] ,ans ,p[N];
bool vis[N];
int find(int x)
{
if (x != p[x]) return p[x]= find(p[x]);
return p[x];
}
void dfs(int x)
{
if (x == 8)
{
for (int i = 1 ;i <= 7 ;i ++) p[i] = i;//初始化并查集
for (int i = 1 ;i <= 7 ;i ++)
{
for (int j = 1 ;j <= 7 ;j ++)
{
if (f[i][j] && vis[i] && vis[j])//如果两点之间可以连接,且需要连接,就连接
{
int a = find(i);
int b = find(j);
if (a != b) p[a] = b;
}
}
}
int flag = 0;
for (int i = 1 ;i <= 7 ;i ++)
{
if (p[i] == i && vis[i]) flag ++;//枚举连通块
}
if (flag == 1) ans ++;//只有连在一起且只有一个连通块的情况才满足题意
return;
}
vis[x] = false;
dfs(x + 1);
vis[x] = true;
dfs(x + 1);
}
int main()
{
f[1][2] = f[1][6] = 1;
f[2][7] = f[2][1] = f[2][3] = 1;
f[3][7] = f[3][4] = f[3][2] = 1;
f[4][3] = f[4][5] = 1;
f[5][7] = f[5][6] = f[5][4] = 1;
f[6][1] = f[6][7] = f[6][5] = 1;
f[7][2] = f[7][6] = f[7][3] = f[7][5] = 1;//a,b,c,d,e,f,g分别对应1234567,用二维数组表示它们相邻
dfs(1);
cout << ans;
return 0;
}
6、
简单题目了可以说,唯一值得注意的四舍五入要会写;
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int main()
{
int sum = 0 ,x = 0 ,y = 0;
int n ;
cin >> n;
while (n --)
{
double a;
cin >> a;
sum ++;
if (a >= 60) x ++;
if (a >= 85) y ++;
}
double xx = x * 1.00000 / sum;
double yy = y * 1.00000 / sum;
if (xx / 1000 >= 0.005) xx += 0.01;
if (yy / 1000 >= 0.005) yy += 0.01;
printf("%.0lf" ,xx * 100);
cout << '%' << endl;
printf("%.0lf" ,yy * 100);
cout << '%';
return 0;
}
7、
字符串的应用,思路并不复杂,主要是考验代码的基本功
#include<bits/stdc++.h>
using namespace std;
int month[13] = {-1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int date, ans1, ans2;
// 判断日期是否回文
bool check1(int date)
{
string s = to_string(date);
if (s[0] == s[7] && s[1] == s[6] && s[2] == s[5] && s[3] == s[4]) return true;
return false;
}
// 判断日期是否满足 ABABBABA 型回文
bool check2(int date)
{
string s = to_string(date);
if (s[0] == s[2] && s[0] == s[5] && s[0] == s[7] && s[1] == s[3] && s[1] == s[4] && s[1] == s[6]) return true;
return false;
}
int main()
{
cin >> date;
int y = date / 10000, m = date / 100 % 100, d = date % 100;
// 枚举合法日期,即枚举合法的年、月、日
for (int i = y ; ; i ++ )
{
if (i % 400 == 0 || (i % 100 != 0 && i % 4 == 0)) month[2] = 29;
else month[2] = 28;
int j = (i == y) ? m : 1;
for ( ; j <= 12 ; j ++ )
{
int k = (i == y && j == m) ? d + 1 : 1;
for( ; k <= month[j] ; k ++)
{
int date = i * 10000 + j * 100 + k;
if (check1(date) && ans1 == 0) ans1 = date;
if (check2(date)) //当找到了 ABABBABA 型回文日期时,结束程序
return cout << ans1 << '\n' << date << '\n', 0;
}
}
}
return 0;
}