目录
1.字符串排序
2.门牌制作
3.即约分数
4.蛇型填数
5.跑步锻炼
6.七段码
7.成绩统计
8.回文日期
9.字串分值和
10.平面切分
1.字符串排序
题目解析:这个题目真没搞懂。有会的大佬教我一下谢谢。
2.门牌制作
题目解析:出过超级多这类题目,就是每位检查有2.
#include <iostream>
using namespace std;
int add(int x)
{
int sum = 0;
while(x)
{
int t = x % 10;
if(t == 2)
sum++;
x /= 10;
}
return sum;
}
int main()
{
int Sum = 0;
for(int i = 1; i <= 2020; i++)
{
Sum += add(i);
}
cout << Sum << endl;
return 0;
}
3.即约分数
题目解析:就是求公约数==1;
#include <iostream>
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 << endl;
return 0;
}
4.蛇型填数
题目解析:就是找规律,
第一行第一列:1
第二行第二列:1+1*4 = 5;
第三行第三列:1 + 1*4 + 2 * 4= 13;
...
所以第二十行第二十列:
1+1*4 + 2*4 + 3 *4 + ...+ 19*4;
#include <iostream>
using namespace std;
int main()
{
int n = 20;
int sum = 1;
for(int i = 0; i < 20; i++)
{
sum += i * 4;
}
cout << sum << endl;
return 0;
}
5.跑步锻炼
题目解析:日期类问题。
#include <iostream>
using namespace std;
int ans = 0;
int Month[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int main()
{
int year = 2000; int month = 1; int day = 1; int weekday = 6;
while(1)
{
ans += (weekday == 1 || day == 1) + 1;
if(year == 2020 && month == 10 && day == 1)
{
break;
}
day++;
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 << ans << endl;
return 0;
}
6.七段码
题目解析:将相邻的边全部放到矩阵当中,采用dfs深搜,将每种每一层进行遍历,方法进行记录并且加和。
#include <iostream>
using namespace std;
int graph[7][7] =
{//转化成矩阵
{1,1,0,0,0,1,0},
{1,1,1,0,0,0,1},
{0,1,1,1,0,0,1},
{0,0,1,1,1,0,0},
{0,0,0,1,1,1,1},
{1,0,0,0,1,1,1},
{0,1,1,0,1,1,1}
};
int f[7] = { 0 };
int dfs(int n, int i)
{
int sum = 1;
for (int k = 0; k < n; k++)
{
if (graph[i][k] == 1 && f[k] == 0)
{
f[k] = 1;
sum +=dfs(7, k);
f[k] = 0;//回溯
}
}
return sum;
}
int main()
{
cout << dfs(7, 0) / 2;
return 0;
}
7.成绩统计
题目解析:简单统计
#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;
}
8.回文日期
题目解析:可以先找到年份在输入年份之间,再对于年份逆置变成月份和日份,并且符合真正日历时间就是一种答案。
#include<iostream>
using namespace std;
int daymonth[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
bool check(int date)
{
int year = date / 10000;
int month = (date / 100) % 100;
int day = date % 100;
if(month < 0 || month > 12) return false;
if(day ==0 || month != 2 && day > daymonth[month]) return false;
if(month == 2 )
{
int leap = year % 100 && year % 4 == 0 || year % 400 == 0;
if(day > daymonth[month] + leap) return false;
}
}
int main()
{
int date1, date2;
cin >> date1 >> date2;
int ans = 0;
for(int i = 1000; i <= 10000; i++)
{
//年份范围
int date = i, x = i;
for(int j = 0; j < 4; j ++ )
date = date * 10 + x % 10, x /= 10;
if(date1 <= date && date <= date2 && check(date))
{
ans++;
}
}
cout << ans << endl;
return 0;
}
9.字串分值和
题目解析: 题目意思可以用一个例子来表示:
f[a] = 1;
f[ab] = 2;
f[aba] = 1;
那么就是相同的字符就会影响贡献点。那么就要想到不把相同的字符放到一起求f[]。
axxxxaxxxxa
那么就要将再次出现的字符和前一次出现的字符之间的字符进行放到f[]求贡献点以及与长度进行相乘。
#include <iostream>
#include<cstring>
using namespace std;
int num[26];
int main()
{
string s;
cin >> s;
int len = s.size();
memset(num, -1, sizeof(num));
long long ans = 0;
for(int i = 0; i < len; i++)
{
ans += (long long)(i - num[s[i] - 'a']) * (len - i);
num[s[i] - 'a'] = i;
}
cout << ans << endl;
return 0;
}
10.平面切分
题目解析:根据下面的图片可以分析出来规律。
(1)如果线是重合不增加面的个数;
(2)线相互平行就在原来基础增加一个面;
(3)相交(但是交点不重合)原来基础增加一个面;
(4)相交(焦点重合)增加一个面。
#include<bits/stdc++.h>
using namespace std;
double A[100005];
double B[100005];
double x[100005];
double y[100005];
int zll(int n)
{//进入该函数,寻找第n条直线与其他直线相交或平行的情况
int remark,num=1;//进入该函数至少加1,所以初始化为1 ,也是整体+1
for(int j=0;j<n;j++)
{
if(A[n]==A[j]) continue;//第n条直线与前面j条平行,跳入下一次循环,因为平行只增加一个平面
remark=0; //若是第n条直线碰到第2条甚至更多平行的直线,不再增加新的平面
x[j]=(B[n]-B[j])/(A[j]-A[n]);//执行到这里只剩下了两种情况,一种是第n条直线与第j条直线相交产生了新的交点
y[j]=A[n]*x[n]+B[n]; //第二种是第n条直线与第j条直线相交,却交到了第j条与其它直线相交的旧交点上
for(int k=0;k<j;k++)
{
if(x[j]==x[k]&&y[j]==y[k])
{
remark=1;//这是第2种情况,不再+1
}
}
if(remark!=1)
{
num++;//不是第2种情况就是第1种情况,产生一个新交点我就再+1
}
}
return num;
}
int main(){
int n,mark=0,sum=1;
cin>>n;
for(int i=0;i<n;i++){
cin>>A[i]>>B[i];
mark=0;
for(int j=0;j<i;j++){
if(A[i]==A[j]&&B[i]==B[j]){//遍历第i条线的前面i-1条是否重复
mark=1;
break;
}
}
if(mark==1)//只要找到重复的,直接跳到下一次循环
continue;//此时实际并没有产生新的平面 ,排除掉了唯一不增加平面的情况
if(i==0){
sum=2;
}
else{//进入else内部每一次相加,zll()的值最少为1
sum=sum+zll(i);
}
}
cout<<sum;
return 0;
}