A.门牌制作
思路:暴力枚举
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int j,ans=0;
for(int i=1;i<=2020;i++)
{
j=i;
while(j!=0)
{
if(j%10==2)
ans++;
j/=10;
}
}
cout<<ans<<endl;
return 0;
}
答案:624
B.既约分数
思路:还是暴力
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int i,j,ans=0;
for(i=1;i<=2020;i++)
{
for(j=1;j<=2020;j++)
{
if(__gcd(i,j)==1)
ans++;
}
}
cout<<ans<<endl;
return 0;
}
答案:2481215
C.蛇形填数
思路:找规律
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int a=1,b=4;
for(int i=2;i<=20;i++)
{
a+=b;
b+=4;
}
cout<<a<<endl;
return 0;
}
答案:761
D.跑步锻炼
思路:典型的日期问题,三重for循环,判断日期时注意简单写法
#include<iostream>
#include<algorithm>
using namespace std;
int judge(int year)
{
if(year%4==0&&year%100!=0||year%400==0)
return 1;
return 0;
}
int main()
{
int day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int y,m,d;
int w=6;
int ans=0;
for(y=2000;y<=2020;y++)
{
for(m=1;m<=12;m++)
{
for(d=1;d<=day[m]+((m==2)?judge(y):0);d++)
{
ans++;
if(w==1||d==1)
ans++;
w=w%7+1;
if(y==2020&&m==10&&d==1)
cout<<ans;
}
}
}
return 0;
}
答案:8879
E.七段码
思路:半年过去了,记得比赛现场好像是现数的,当时想不出思路有点慌,就直接上手数了... 欠下的总是要还的...
对1—7进行全排列,由于发光的二极管数量不定,对每一个排列数,截取它的前2个、前3个、前4个...前7个数字,分别进行连续性判断(这里没有前1个,因为1个的不用算,直接最后答案加7即可)。若连续,将这几个数字排序后存入set中。对每一个排列数的每一个前缀都处理完(二重循环),最后输出set中的元素个数+7。
代码:
#include<iostream>
#include<algorithm>
#include<set>
using namespace std;
set<string>s;
set<string>::iterator it;
string c;
int main()
{
int i,j,n=7;
int a[7]={1,2,3,4,5,6,7};
do
{
for(i=0;i<6;i++)
{
int book=1;
if(a[i]==1&&a[i+1]!=6&&a[i+1]!=2) book=0;
if(a[i]==2&&a[i+1]!=1&&a[i+1]!=3&&a[i+1]!=7) book=0;
if(a[i]==3&&a[i+1]!=2&&a[i+1]!=7&&a[i+1]!=4) book=0;
if(a[i]==4&&a[i+1]!=3&&a[i+1]!=5) book=0;
if(a[i]==5&&a[i+1]!=4&&a[i+1]!=6&&a[i+1]!=7) book=0;
if(a[i]==6&&a[i+1]!=1&&a[i+1]!=5&&a[i+1]!=7) book=0;
if(a[i]==7&&a[i+1]!=2&&a[i+1]!=3&&a[i+1]!=5&&a[i+1]!=6) book=0;
if(book==0)
break;
c.clear();
for(j=0;j<=i+1;j++)
c+='0'+a[j];
sort(c.begin(),c.end());
s.insert(c);
}
}
while(next_permutation(a,a+n));
cout<<s.size()+7<<endl;
for(it=s.begin();it!=s.end();it++)
cout<<*it<<endl;
return 0;
}
答案:80
F:成绩统计
思路:水题
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
int main()
{
int n,i,x,a=0,b=0;
cin>>n;
for(i=0;i<n;i++)
{
cin>>x;
if(x>=85)
a++;
if(x>=60)
b++;
}
cout<<round(b*100.0/n)<<"%"<<endl;
cout<<round(a*100.0/n)<<"%"<<endl;
return 0;
}
G:回文日期
思路:一天一天的枚举比较好写,注意日期的一些细节以及简写,注意隐藏条件A!=B。
#include<iostream>
#include<algorithm>
#include<set>
using namespace std;
int judge(int m)
{
if(m%4==0&&m%100!=0||m%400==0)
return 1;
return 0;
}
int judge1(int a,int b,int c)
{
if(a/1000==c%10&&a%1000/100==c/10&&a%100/10==b%10&&a%10==b/10)
return 1;
return 0;
}
int judge2(int a,int b,int c)
{
if(a/1000==a%100/10&&a%100/10==b%10&&b%10==c%10&&c%10!=c/10&&c/10==b/10&&b/10==a%10&&a%10==a%1000/100)
return 1;
return 0;
}
int main()
{
int day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
string s;
cin>>s;
int a,b,c,a1,b1,c1,d;
a=(s[0]-'0')*1000+(s[1]-'0')*100+(s[2]-'0')*10+(s[3]-'0');
b=(s[4]-'0')*10+(s[5]-'0');
c=(s[6]-'0')*10+(s[7]-'0');
a1=a,b1=b,c1=c;
while(1)
{
d=day[b];
if(b==2)
d+=judge(a);
if(c<d)
c++;
else
{
if(b<12)
{
b++;
c=1;
}
else
{
a++;
b=1;
c=1;
}
}
if(judge1(a,b,c)==1)
break;
}
printf("%04d%02d%02d\n",a,b,c);
a=a1,b=b1,c=c1;
while(1)
{
d=day[b];
if(b==2)
d+=judge(a);
if(c<d)
c++;
else
{
if(b<12)
{
b++;
c=1;
}
else
{
a++;
b=1;
c=1;
}
}
if(judge1(a,b,c)==1&&judge2(a,b,c)==1)
break;
}
printf("%04d%02d%02d\n",a,b,c);
return 0;
}
H:子串分值和
思路:当时好像是两重循环暴力的,记不太清了,如果是这样肯定没有得全分。
这道题的代码很短,也很考验思维。
采取一种不常规的思维,不去枚举每一个子串,然后计算不相同的字母数;而是计算每个字母作为一个种类,在不同的子串中被加的次数。被加的次数就是:(这个字母的位置-上次它出现的位置)*(这个字母的位置距离串尾的距离)。自行枚举进行理解。
一开始的位置都初始化为-1,表示还没出现过。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<string>
#include<cstring>
using namespace std;
string s;
int book[30];
int main()
{
memset(book,-1,sizeof(book));
string s;
cin>>s;
int n=s.length(),i,ans=0;
for(i=0;i<n;i++)
{
ans+=(i-book[s[i]-'a'])*(n-i);
book[s[i]-'a']=i;
}
cout<<ans<<endl;
return 0;
}