一、门牌制作
思路:枚举每一位数,看是否等于2,是的话++;
#include<iostream>
using namespace std;
int ans;
void solve(int k)
{
while (k > 0)
{
int m = k % 10;
k /= 10;
if (m == 2)
{
ans++;
}
}
}
int main()
{
for (int i = 1; i <= 2020; i++)
{
solve(i);
}
cout << ans << endl;
return 0;
}
二、既约分数
思路;利用gcd函数,枚举数字后判断是否 符合条件,最后乘二(因为数字可以上下交换)再加一(记得算上1/1)的情况。
#include<iostream>
using namespace std;
int gcd(int a,int b) {
return b>0 ? gcd(b,a%b):a;
}
int main()
{
long long int cnt=0;
for(int i=1;i<=2020;i++){
for(int j=i+1;j<=2020;j++){
if(gcd(i,j)==1) cnt++;
}
}
cout<<cnt*2+1;
return 0;
}
三、蛇形填数
思路:找规律,n+1行的数等于第n行数字加n*(n-1).
#include <bits/stdc++.h>
using namespace std;
int main() {
int step = 4, n = 1, res = 1;
while(res ++) {
if(res == 21) break;
n += step; step += 4;
}
cout << n << endl;
return 0;
}
四、七段码
思路;判断二极管是否相连,可以先用二维数组标记两两相连的二极管,再枚举亮灯的情况,利用深搜(dfs)判断枚举出的灯是否相连,再利用并查集将相连的二极管块连在一起,最后判断是否只有一组数据,是的话说明所有二极管都连在了一起。
#include <iostream>
#include <cstring>
using namespace std;
const int MAXN = 25;
int n = 7, ans = 0, path[MAXN], f[MAXN][MAXN], father[MAXN];
int find(int x)
{
if (x != father[x]) {
return father[x] = find(father[x]);
}
return father[x];
}
void dfs(int u, int p, int m)
{
if (u == m) {
for (int i = 1; i < MAXN; ++i) {
father[i] = i;
}
for (int i = 0; i < m; ++i) {
for (int j = i + 1; j < m; ++j) {
//存在边相连
if (f[path[i]][path[j]] == 1) {
//path[i] 和 path[j] 合并成一个集合
father[find(path[i])] = find(father[path[j]]);
}
}
}
bool flag = false;
for (int i = 0; i < m - 1; ++i) {
if (find(path[i]) != find(path[i + 1])) {
flag = true;
break;
}
}
if (!flag) {
++ans;
}
return ;
}
for (int i = p; i <= n; ++i) {
path[u] = i;
dfs(u + 1, i + 1, m);
}
}
int main()
{
//A B C D E F G
//1 2 3 4 5 6 7
memset(f, 0, sizeof(f));
f[1][2] = f[2][1] = 1;
f[1][6] = f[6][1] = 1;
f[2][7] = f[7][2] = 1;
f[6][7] = f[7][6] = 1;
f[7][3] = f[3][7] = 1;
f[7][5] = f[5][7] = 1;
f[2][3] = f[3][2] = 1;
f[3][4] = f[4][3] = 1;
f[4][5] = f[5][4] = 1;
f[5][6] = f[6][5] = 1;
for (int i = 1; i <= n; ++i) {
dfs(0, 1, i);
}
cout << ans << endl;
return 0;
}
五、跑步锻炼
思路:模拟,但是要注意闰年的判断和每个月的月数。
#include<iostream>
using namespace std;
int ants = 0;
int Month[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
int main()
{
int year = 2000, month = 1, day = 1, weekday = 6;
while (1)
{
ants += (weekday == 1 || day == 1) + 1;
if (year == 2020 && month == 10 && day == 1)
{
break;
}
day += 1;
weekday = (weekday + 1) % 7;
if (month == 2 && (year % 4 == 0 && year % 100 != 0 || year % 400 == 0))
{
if (day > Month[month] + 1)
{
day = 1;
month += 1;
}
}
else if (day > Month[month])
{
day = 1;
month += 1;
}
if (month == 13)
{
month = 1;
year += 1;
}
}
cout << ants << endl;
return 0;
}
六、回文日期
思路:需要用字符串和数字之间的转换,然后判断一个日期是否是回文串,日期是否合法,在前面的基础上再判断是否是ABBABABA即可。
#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <bits/stdc++.h>
using namespace std;
int data;
int mon[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
bool fun(int n){
string s="";
while(n){
int temp=n%10;
s+=temp-'0';
n/=10;
}
string m=s;
reverse(s.begin(),s.end());
return m==s?true:false;
}
bool sfun(int n){
string s="";
while(n){
int temp=n%10;
s+=temp-'0';
n/=10;
}
string m=s;
reverse(s.begin(),s.end());
if(s!=m) return false;
if(s[2]!=s[0]) return false;
if(s[3]!=s[1]) return false;
if(s[4]!=s[1]) return false;
if(s[5]!=s[0]) return false;
if(s[6]!=s[1]) return false;
if(s[7]!=s[0]) return false;
return true;
}
bool year(int n){
int mday=n%100;
int mmon=(n%10000-mday)/100;
int myea=(n-n%10000)/10000;
if((myea%4==0&&myea%100!=0)||(myea%400==0)) mon[2]++;
if(mmon>12) return false;
if(mday>mon[mmon]) return false;
return true;
}
int main(){
cin>>data;
int temp;
for(int i=data+1;;i++){
if(fun(i)){
if(year(i)){
cout<<i<<endl;
temp=i;
break;
}
}
}
for(int i=temp;;i++){
if(sfun(i)){
if(year(i)){
cout<<i<<endl;
break;
}
}
}
return 0;
}
七、字串排序
思路:1、逆序数等于冒泡排序冒泡交换的次数
#include <bits/stdc++.h>
using namespace std;
const int N = 1e4 + 10;
char ans[N], res[N];
int n, len;
bool judge()
{
int i = len;
while(ans[i] == res[i] && i) i--;
return res[i] < ans[i];
}
void dfs(int now, int maxn, int m, int sum) {
if(sum == n)
{
if(m < len || (m == len && judge()))
{
len = m;
for(int i = 1; i <= len; i++) ans[i] = res[i];
}
return;
}
if(now >= 26) return ;
for(int i = 1; i <= maxn; i++)
{
int temp = sum + m * i;
if(temp > n) return ;
res[m + i] = char(now + 'a');
dfs(now + 1, i, m + i, temp);
}
}
int main()
{
len = 0x3f3f3f3f;
scanf("%d", &n);
dfs(0, 8, 0, 0);
for(int i = len; i >= 1; i--)
putchar(ans[i]);
return 0;
}
八、成绩统计
思路:先就是对这个数+0.5然后强制成Int就成了,但是也要注意四舍五入的情况。
#include <iostream>
using namespace std;
int main()
{
double a = 0;
double b = 0;
double c;
cin >> c;
int n;
for (int i = 0; i < c; i++)
{
cin >> n;
if (n >= 60)
{
a++;
}
if (n >= 85)
{
b++;
}
}
int x =(a * 100.0)/c+0.5;
int y =(b * 100.0)/c+0.5;
cout << x << "%" << endl << y << "%";
return 0;
}
九、字串分值和
思路:采用的是贡献值方法
#include <iostream>
using namespace std;
int last[30];
long long ans = 0;
int main() {
string s;
cin >> s;
int len = s.length();
s = '0' + s;
for (int i = 1; i <= len; i++) {
ans += (long long)(len - i + 1) * (i - last[s[i]-'a']);
last[s[i]-'a'] = i;
}
cout << ans;
return 0;
}
十、平面切分
思路:下面的直线都优先进行去重,然后进行接下来操作
1.如果新增的直线和一个直线平行,那么就+1
2.如果新增的直线与平面内所有的直线有交点,且这个交点和之前的交点不一样(交点用set去重)那么增加的分割数就是交点数+1。
#include <iostream>
#include <set>
#include <bits/stdc++.h>
using namespace std;
int n;
double A[1005],B[1005];
int main(){
cin>>n;
set<pair<double,double> >a;
while(n--){
double x;
double y;
cin>>x>>y;
a.insert(pair<double,double>(x,y));
}
set<pair<double,double> >:: iterator it=a.begin();
for(int i=0;i<a.size();i++){
A[i]=it->first;
B[i]=it->second;
it++;
}
long long ans = 2;
for(int i = 1; i < a.size(); i++)
{
set<pair< double, double> > pos;
for(int j = 0; j <= i-1; j++)
{
double a1 = A[i], b1 = B[i];
double a2 = A[j], b2 = B[j];
if(a1 == a2) continue;
double x= (b2-b1)/(a1-a2);
double y= a1*(b2-b1)/(a1-a2) + b1;
pos.insert(pair<double,double>(x,y));
}
ans += pos.size() + 1;
}
cout<<ans<<endl;
return 0;
}