#includeint main(){ int cnt=0; for(int i=1;i<=2020;i++){ for(int j=i;j>0;j=j/10){ if(j%10==2){ cnt++; } } } //例如2000->0 //200->0 //20->0 //2->2--->cnt ++ printf("%d",cnt); return 0; }
答案:624
第二题、既约分数#includeint gcd(int a,int b){ int ret = 0; int cnt = 0; if(a%b==0) ret = b; else ret = gcd(b,a%b); }//求最大公约数 int main(){ double a=0,b=0; int cnt = 0; for(a=1;a<=2020;a++){ for(b=1;b<=2020;b++){ if(gcd(a,b)==1){ cnt ++; } } } printf("%d",cnt); return 0; }
答案:2481215
第三题、蛇形填数(1,1):1 + (1-1)^4 = 1
(2,2):1 + (2-1)^4 = 5
(3,3):5 + (3-1)^4 = 13
(4,4):13 + (4-1)^4 = 25
(5,5):25+ (5-1)^4 = 41
得出结论:(n-1)^2+n^2=(n,n)的结果,即20^2+19^2=761
答案:761
第四题、跑步锻炼首先设一个月份的数组,用来记录每个月的天数,然后考虑闰年和平年对二月天数的影响。
因为题目问的是多少千米,那么普通天数就相当于1千米,总和公式为:
2000.1.1~2020.10.1总天数 + 2000.1.1~2020.10.1中是月初但不是周一的天+2000.1.1~2020.10.1中周一的天数
是月初但不是周一的天数要设一个判断条件if((截至目前的总天数 + 6) % 7 != 1)
{因为他说了2000.1.1是周六,就相当于原数从Sun开始整体向右移了六个单位,这样是不是更好理解了}
比如说2000.1的日历
将1月补齐需要整除7减2加6,因此(sum - 2 + 6) / 7就是这么来的
#includeint main(){ int sum = 0, s = 0; int month[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; for(int i = 2000; i < 2020; i++) { if(i % 4 == 0 && i % 100 != 0 || i % 400 == 0) { month[2]++; //闰年的话二月加一 } for(int i = 1; i <= 12;i++) { if((sum + 6) % 7 != 1) { s++; //计算是月初且不是周一的日子 } sum += month[i]; } if(month[2] == 29) { month[2]--; } //避免闰年的二月重复加一 } month[2]++; //2020年的前9个月 for(int i = 1; i <= 9; i++) { if((sum + 6) % 7 != 1) { s++; //计算是月初且不是周一的日子 } sum += month[i]; } //加上2020.10.1日 sum += 1; s++; int z = sum + s + (sum - 2 + 6) / 7; printf("%d",z); return 0; }
答案:8879
第五题、七段码#includeint ans; int e[10][10],p[10],use[10]; void init() //连边建图 { e[1][2]=e[1][6]=1; e[2][1]=e[2][7]=e[2][3]=1; e[3][2]=e[3][4]=e[3][7]=1; e[4][3]=e[4][5]=1; e[5][4]=e[5][6]=e[5][7]=1; e[6][1]=e[6][5]=e[6][7]=1; } int find(int x){ //并查集 if(p[x] != x) p[x] = find(p[x]); return p[x]; } void dfs(int d){ if(d==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(e[i][j]&&use[i]&&use[j]) p[find(i)]=find(j); //用并查集把相邻的亮边存放到一个P集合里,根节点为第一个边的序号 int k=0; for(int i=1;i<=7;i++) if(use[i] && p[i]==i) k++; if(k==1) //所有亮边都在同一个集合中 ans++; return; } use[d]=1; //打开d这个灯,继续开关下一个灯 dfs(d+1); use[d]=0; //关闭d这个灯,继续开关下一个灯 dfs(d+1); } int main() { init(); dfs(1); printf("%d",ans); }
答案:80
第六题:成绩统计#include第七题 :回文日期int main(){ int n,s;//用n表示总人数,s表示学生的分数 int a=0,b=0;//a代表合格人数,b代表优秀的人数 float p,e; scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&s); if(s>=60){ a++; } if(s>=85){ b++; } } p=(float)a/n*100; e=(float)b/n*100; int P=(int)(p+0.5);//P代表及格率,E代表优秀率 int E=(int)(e+0.5);//四舍五入变成整数百分比 printf("%d%%n%d%%",P,E);//两个%%才能得到XX% return 0; }
#include第八题:子串分值和int F(int x){ int t; if(x%400==0||x%4==0&&x%100!=0) t = 1; else t = 0; return t; } //判断是否为闰年 ,防止输入不合法日期 int main(){ int a[12]={31,28,31,30,31,30,31,31,30,31,30,31}; int x; scanf("%d",&x); int y=x/10000;//输入的年 int m=x%10000/100;//输入的月 int d=x%100;//输入的日 int flag=0; int c=y%10*10+y%100/10;//年对应的回文月 int b=y/100%10*10+y/1000;//年对应的回文日 if(F(y)) a[1]=29; else a[1]=28; if((c>m&&c<13)||(c==m&&b>d&&b<=a[c-1])){//当年对应的回文日期在输入的日期之后 flag=1; } if((y/1000!=y%10)&&(y%100==c%10*10+c/10)&&(c==b)){//判断当年对应的回文日期是否是ABABBABA型日期 flag=0; } while(y<=8999){ y++; m=y%10*10+y%100/10;//年份回文月 d=y/100%10*10+y/1000;//年份回文日 if(m>12||d>31) continue; if((flag!=1)&&m>0&&m<13&&d>0&&d<=a[m-1]){//找回文型 if(m<10){ printf("%d0%d%dn",y,m,d); }else if(d<10){ printf("%d%d0%dn",y,m,d); }else{ printf("%d%d%dn",y,m,d); } flag=1; } if((y/1000!=y%10)&&(y%100==m%10*10+m/10)&&(m==d)){ if(m<10){ printf("%d0%d%dn",y,m,d); }else if(d<10){ printf("%d%d0%dn",y,m,d); }else{ printf("%d%d%dn",y,m,d); } break; } } return 0; }
#include第九题:平面切分//使用动态规划比较好理解 #include #include #define ll long long using namespace std; const int maxn=2e5+10; ll ans;//总个数->定义为long long ,否则会爆 int id[30][maxn];//每个字母的id 对应的位置 int cnt[30];//字母id 对应的数量 char a[maxn];//定义字符数组 int b[30];//各个字符区间段位置 int main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin>>a+1; //记得加1 int len=strlen(a+1); // cout< =i)//这个字母在i后面 { int t=lower_bound(id[j],id[j]+1+cnt[j],i)-id[j];//就是二分查找 b[++front] =id[j][t];//不同字符出现的第一个位置 } } sort(b+1,b+1+front);//对i后面出现的字母排一下序 int last=i;//当前正在索引的位置 for(int j=2;j<=front;j++)//跑一遍下一个位置 ->其实这里就是第几个不同字符 { ans+=(b[j]-last)*(j-1); //b[j]-last是该位字母去上一个字母=距离差 ->其实就是有几个重复的这样的块 //然后再 * 这个块的长度,当前字符位置-1,其实就是对前面的做处理 //只是需要当前这个字符做标志,j-1是除去当前字符,然后将(b[j]-last)个段 *(前面不同字符个数j-1); last=b[j];//将索引位置更新 } ans+=(len-last+1)*front; //最后的位置,就是最长的一个段; } cout<
#includeusing namespace std; long double s[1010][2];//存储直线的A,B long long ans; bool st[1010]; //false表示不是重边 pair p; int main(){ int n; cin>>n; for(int i=0;i >s[i][0]>>s[i][1]; set > points; for(int j=0;j 第十题:字串排序 #include#include #include using namespace std; const int N = 135, M = 10010; int f[N][30][N];//chcnt[i][j]记录第i个位置取字母j+'a'的逆序对最大值 int chcnt[N][30];//mlen[i]记录每个位置的最大值 int mlen[N]; void dp() { for (int i = 2; i < N; ++i) { int m = 0; for (int j = 1; j <= 'z' - 'a'; ++j) { for (int k = 1; k < i; ++k) { if (k > 1) f[i][j][k] = f[i - 1][j][k - 1] + i - k; else f[i][j][k] = chcnt[i - 1][j - 1] + i - 1; chcnt[i][j] = max(chcnt[i][j], f[i][j][k]); } m = max(m, chcnt[i][j]); } mlen[i] = m; } } int main() { dp(); int score = 0; cin >> score;//找出最短长度值 int beg = 0; for (int i = 1; i < N; ++i) if (mlen[i] >= score) { beg = i; break; } int curr = 0; //用于记录逆序值 int same = 1; //记录后缀中有多少个相同字母 char last = 'z' + 1;//记录上一个字母是什么 for (int i = beg; i > 0; --i) { //从a开始枚举 int j = 0; for (; j <= last - 'a'; ++j) { if (j == last - 'a') curr -= same; if (curr + chcnt[i][j] >= score) { curr += i - 1; break; } } if (j == last - 'a') same++; else { last = j + 'a'; same = 1; } cout << last; } cout << endl; return 0; } 欢迎分享,转载请注明来源:内存溢出
评论列表(0条)