A:门牌制作
思路:根据题目模拟
//624
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int res;
int main()
{
for(int i=1;i<=2020;i++)
{
int x=i;
while(x)
{
int a=x%10;
if(a==2) res++;
x/=10;
}
}
cout<<res<<endl;
return 0;
}
B既约分数
思路:暴力判断1~2020的每个数
//2481215
//忘记考虑 1/1了
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int gcd(int a,int b)
{
return b?gcd(b,a%b):a;
}
int main()
{
int res=0;
for(int i=1;i<=2020;i++)
for(int j=1;j<=2020;j++)
{
if(gcd(i,j)==1) res++;
}
cout<<res<<endl;
return 0;
}
C蛇形填数
思路:
找规律可以得到
对角线的数 = 其左上角的数 + 行号 * 4 (行号从0开始计算)
//761
//这道题我们找规律找出来的,每个对角线上的数都等于其当前所在的行数*4+其左上角的数。行数从0开始计算
#include<iostream>
using namespace std;
int main()
{
int res=1;
for(int i=1;i<=19;i++)
{
res=res+(4*i);
}
cout<<res<<endl;
return 0;
}
D七段码
思路:DFS+并查集
DFS暴力枚举每一种方案,然后再判断每种方案是否合理。
//dfs+并查集
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=10;
int st[N],p[N],e[N][N];
int res;
int find(int x)
{
if(p[x]!=x) p[x]=find(p[x]);
return p[x];
}
void dfs(int u)
{
if(u>7)
{
//初始化每个头结点
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(e[i][j]&&st[i]==1&&st[j]==1)
{
p[find(i)]=find(j);
}
}
int cnt=0;
for(int i=1;i<=7;i++)
{
if(p[i]==i&&st[i]==1) cnt++;
}
if(cnt==1) res++;
return;
}
//这条边亮
st[u]=1;
dfs(u+1);
//这条边不亮
st[u]=2;
dfs(u+1);
}
int main()
{
//初始化每条连接的边
e[1][2]=e[1][6]=1;
e[2][1]=e[2][7]=e[2][3]=1;
e[3][2]=e[3][7]=e[3][4]=1;
e[4][3]=e[4][5]=1;
e[5][4]=e[5][7]=e[5][6]=1;
e[6][1]=e[6][7]=e[6][5]=1;
e[7][2]=e[7][3]=e[7][5]=e[7][6]=1;
dfs(1);
cout<<res<<endl;
return 0;
}
E跑步锻炼
思路:模拟
//答案是8879
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int months[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int res;
int main()
{
int year=2000;
int month=1;
int day=1;
int today=6;
while(true)
{
today=today%7;
if(today==1||day==1)
{
res+=2;
}else res+=1;
today++;
day++;
int leap=((year%100!=0&&year%4==0)||year%400==0);
if(month==2)
{
if(day>months[2]+leap)
{
day=1,month++;
if(month>12) year++,month=1;
}
}
else
{
if(day>months[month])
{
day=1,month++;
if(month>12) year++,month=1;
}
}
if(year==2020&&month==10&&day==2)
{
break;
}
}
cout<<res<<endl;
return 0;
}
F回文日期
先枚举回文数,然后再判断日期是否合理
#include<iostream>
#include<algorithm>
#include<cstring>
#define endl "\n"
#define IOS std::ios::sync_with_stdio(false);cin.tie(0); cout.tie(0);
using namespace std;
int months[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int T;
bool check(int date)
{
int year=date/10000;
int month=date%10000/100;
int day=date%100;
if (!month||month>=13||!day) return false;
if (month!=2&&day>months[month]) return false;
if (month==2)
{
bool leap=year%4==0&&year%100||year%400==0;
if (day>28+leap) return false;
}
return true;
}
int main()
{
IOS;
scanf("%d",&T);
while(T--)
{
int date1;
scanf("%d",&date1);
for(int i=0;i<10000;i++)
{
int x=i;
int date=i;
for(int j=0;j<4;j++)
{
date=date*10+(x%10);
x/=10;
}
if(date>date1&&check(date))
{
cout<<date<<endl;
break;
}
}
for(int i=10;i<100;i++)
{
int x=i;
int date=i;
date=date*10+x/10;
date=date*10+x%10;
date=date*10+x%10;
date=date*10+x/10;
date=date*10+x%10;
date=date*10+x/10;
if(date>date1&&check(date))
{
cout<<date<<endl;
break;
}
}
}
return 0;
}
G字串排序
不会喵~
H成绩统计
思路:模拟
#include<iostream>
#include<cstring>
#include<cmath>
#include<cmath>
using namespace std;
int n,res1,res2;
int main()
{
scanf("%d",&n);
int x=n;
while(x--)
{
int x;
scanf("%d",&x);
if(x>=60) res1++;
if(x>=85) res2++;
}
printf("%.0lf%\n",(1.0*res1/n)*100);
printf("%.0lf%\n",(1.0*res2/n)*100);
return 0;
}
思路:
对于每个字母,它在包含它的子串中可能是起点也可能是中间的点,在字符串中向左找到所有包含它的子串的最大起点的位置,就是last[s[i]]+1(last表示这个字母上一次出现的位置),然后向右可以一直到字符串末尾,(i-last[s[i]])*(n-i+1)就是该字母贡献值;
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
int last[26];
ll res;
int main()
{
string s;
cin>>s;
int n=s.size();
s="?"+s;
for(int i=1;i<=n;i++)
{
res+=(ll)( i - last[s[i]-'a'] ) * ( n - i + 1 );
last[s[i]-'a']=i;
}
cout<<res<<endl;
return 0;
}
J平面切分
计算几何:
当我们插入一条线,这条线与平面当前的线都不重合,那么平面必+1
如果这条线与平面中的线有交点,那么平面再+交点的个数
#include<iostream>
#include<cstring>
#include<algorithm>
#include<set>
using namespace std;
typedef pair<double,double> PDD;
set<PDD> lines;//线的集合
int n;
int res=1;//一开始平面的个数为1
int cmp(double c,double d)//该函数返回当前这个直线和集合中的直线相交的点的个数
{
set<PDD> points;//点的集合
PDD point;//点
for(auto it : lines)
{
double a=it.first,b=it.second;
if(a!=c)
{
double x1=(d-b)/(a-c);
double y1=c*x1+d;
points.insert({x1,y1});
}
}
return points.size();
}
int main()
{
cin>>n;
while(n--)
{
double a,b;
cin>>a>>b;
int count1=lines.size();//还没有将当前的线放入到集合中时,线的数量
lines.insert({a,b});//将这个线放入到我们的集合中
if(lines.size()!=count1)
{
res++;//说明这条线不合集合中任意一个线重合
res+=cmp(a,b);
}
}
cout<<res<<endl;
return 0;
}