调试小记1既约分数2 蛇形填数3跑步锻炼4七段码5蚂蚁感冒6地宫取宝7带分数

本文主要是介绍调试小记1既约分数2 蛇形填数3跑步锻炼4七段码5蚂蚁感冒6地宫取宝7带分数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

20省2-2- 既约分数


https://vijos.org/d/gadflycq/contest/601bf6daf413621b7b360286/1041
【问题描述】
如果一个分数的分子和分母的最大公约数是 1,这个分数称为既约分数。
例如, \frac{3}{4}
4
3

, \frac{5}{2}
2
5

, \frac{1}{8}
8
1

, \frac{7}{1}
1
7

(即 3/4,5/2,1/8,7/1)都是既约分数。
请问,有多少个既约分数,分子和分母都是 1 到 2020 之间的整数(包括 1和 2020)?

【输入】
没有输入。

【输出】
输出一个整数。
考试时的代码:
要知道什么是最大公约数:
最大公约数是两个整数共有的因子中最大的那一个,最大公约数也叫最大公因子。a,b的最大公约数记为(a,b),同样的,a,b,c的最大公约数记为(a,b,c),多个整数的最大公约数也有同样的记号。求最大公约数有多种方法,常见的有质因数分解法、短除法、辗转相除法、更相减损法。与最大公约数相对应的概念是最小公倍数,a,b的最小公倍数记为[a,b]。

#include <bits/stdc++.h>using namespace std;int main()
{int a,b,c,d,i,s=0,flag=0;for(a=1;a<=2020;a++)for(b=1;b<=2020;b++){c=a;d=b;for(i=2;i<=c;i++){if(d%c==0||(d%i==0&&c%i==0))//if(d%i==0&&c%i==0){flag=1;break;}else continue;}if(flag==0) s++;}printf("%d",s);return 0;
}

答案:2481215
这道题重点在判断最大公约数上,这里我们利用递归和正则表达式,实现辗转相除法求最大公约数。(也是我考试时薄弱的地方)
greatest common divisor(gcd) 最大公约数

#include <bits/stdc++.h>using namespace std;
int zdgy(int i,int j){return (!j)?i:zdgy(j,i%j);
}
int main()
{int num=2020,s=0;for(int i=1;i<=num;i++)for(int j=1;j<=num;j++){if(zdgy(i,j)==1)s++;}printf("%d",s);return 0;
}

重要内容:如下代码,递归和三目运算

#include <bits/stdc++.h>using namespace std;
int gcd(int i,int j){//zdgy(i,j)求i,j的最大公约数return (!j)?i:gcd(j,i%j);
}
int main()
{int s=gcd(3,5);//求两个数的最大公约数printf("%d",s);return 0;
}

答案:761
原始的两个数相乘再除以最大公约数就是最小公倍数。

#include <bits/stdc++.h>using namespace std;
int gcd(int i,int j){//zdgy(i,j)求i,j的最大公约数return (!j)?i:gcd(j,i%j);
}
int main()
{int s=gcd(2,4);//求两个数的最大公约数printf("最大公约数%d",s);printf("最小公倍数%d",8/gcd(2,4));return 0;
}

20省2-3- 蛇形填数

https://vijos.org/d/gadflycq/contest/601bf6daf413621b7b360286/1042
【问题描述】
如下图所示,小明用从 1 开始的正整数“蛇形”填充无限大的矩阵

1 2 6 7 15 ……
3 5 8 14 ……
4 9 13 ……
10 12 ……
11 ……
……

容易看出矩阵第二行第二列中的数是 5。请你计算矩阵中第 20 行第 20 列的数是多少?

【输入】
没有输入。

【输出】
输出一个整数。

考试时,我在尝试找对角线的规律,找了很久没找出来。
参考别的:1 5 13 25 规律是 代码很快就出来了
在这里插入图片描述

#include <bits/stdc++.h>using namespace std;int main()
{int a[50];a[1]=1;for(int i=2;i<=20;i++){a[i]=a[i-1]+4*(i-1);}printf("%d",a[20]);return 0;
}

解法二暴力遍历:用二维数组模拟蛇形填数过程

#include <bits/stdc++.h>using namespace std;int main()
{int a[50][50];a[0][0]=1;int x=0,y=0,z=1;while(z<=1000){y++;while(x>=0&&y>=0){a[x][y]=++z;if(y==0) break;x++;y--;}x++;while(x>=0&&y>=0){a[x][y]=++z;if(x==0)break;x--;y++;}}printf("%d",a[19][19]);return 0;
}

20省2-4- 跑步锻炼


https://vijos.org/d/gadflycq/contest/601bf6daf413621b7b360286/1043
小蓝每天都锻炼身体。
正常情况下,小蓝每天跑 1 千米。如果某天是周一或者月初( 1 日),为了激励自己,小蓝要跑 2 千米。如果同时是周一或月初,小蓝也是跑 2 千米。
小蓝跑步已经坚持了很长时间,从 2000 年 1 月 1 日周六(含)到 2020 年10 月 1 日周四(含)。请问这段时间小蓝总共跑步多少千米?

【输入】
没有输入。

【输出】
输出一个整数。
解法一:模拟

#include <bits/stdc++.h>using namespace std;int month[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};int main() {int y = 2000, m = 1, d = 1, w = 6, ans = 0;while(1){ans+=1+(d==1||w==1);//注意这个和下面一行的顺序if(y==2020&&m==10&&d==1) break;d++;w=(w+1)%7;if((y%400==0||(y%4==0&&y%100!=0))&&m==2){if(d>month[m]+1) {d=1,m++;}}else if(d>month[m]){d=1,m++;}if(m==13) {y++,m=1;}}printf("%d\n", ans);return 0;
}

答案:8879
这个代码让我想起也可以这样写来计算两个日期相差的天数,代码如下:

#include <bits/stdc++.h>
using namespace std;
int month[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int main() {int y = 2000, m = 1, d = 1,  ans = 0;while(1){//注意这个和下面一行的顺序if(y==2020&&m==10&&d==1) break;ans+=1;d++;if((y%400==0||(y%4==0&&y%100!=0))&&m==2){if(d>month[m]+1) {d=1,m++;}}else if(d>month[m]){d=1,m++;}if(m==13) {y++,m=1;}}printf("%d\n", ans);return 0;
}

运行结果和用计算器算的一样

20省2-5- 七段码


https://vijos.org/d/gadflycq/contest/601bf6daf413621b7b360286/1044
【问题描述】
小蓝要用七段码数码管来表示一种特殊的文字。

上图给出了七段码数码管的一个图示,数码管中一共有 7 段可以发光的二极管,分别标记为 a, b, c, d, e, f, g。

(若图片无法显示,可参考如下示意图,从顶段开始顺时针依次标记为a,b,c,d,e,f,中间的横段标记为g)

   a----

f | | b
---- → g
e | | c
----
d
Copy
小蓝要选择一部分二极管(至少要有一个)发光来表达字符。在设计字符的表达时,要求所有发光的二极管是连成一片的。
例如: b 发光,其他二极管不发光可以用来表达一种字符。
例如: c 发光,其他二极管不发光可以用来表达一种字符。这种方案与上一行的方案可以用来表示不同的字符,尽管看上去比较相似。
例如: a, b, c, d, e 发光, f, g 不发光可以用来表达一种字符。
例如: b, f 发光,其他二极管不发光则不能用来表达一种字符,因为发光的二极管没有连成一片。
请问,小蓝可以用七段码数码管表达多少种不同的字符?

【输入】
没有输入。

【输出】
输出一个整数。
【参考思路】:
把边看成一个一个的点,相邻的边有边(无向),之后求随机选取x(x>0&&x<=7)条边,使它们构成一个连通图。
是否选择这条边用0和1来表示,所以所有情况就是1~127的二进制,
最后通过dfs来判断连通图

#include <stdio.h>
#include <string.h>int vis[10][10]={0};		//各段邻接矩阵,相邻为1,不相邻为0
int ans[10];				//每次选择哪几段,选择的段为1,未选择为0
int men[10];				//存放访问标记void dfs(int pos)
{for (int i=1;i<8;i++)if ( vis[pos][i] && ans[i] && men[i]==0 )	//如果与上一段的联通,且被选择,且未被标记过,则将其标记{men[i]=1;dfs(i);}	
}bool check()
{int sum=0;memset(men,0,sizeof(men));for (int i=1;i<8;i++)if (ans[i] && men[i]==0)	//如果存在一段被选择,且该段未被之前的深搜访问标记过,则是新的一个独立段{sum++;					//每有一个新的独立段,sum就+1		men[i]=1;dfs(i);}if (sum==1)			//如果sum等于1,就表示只有一个连通域return true;elsereturn false;
}int main()
{int i,num=0;vis[1][2]=vis[2][1]=1;		//a-g对应1-7vis[1][6]=vis[6][1]=1;vis[2][3]=vis[3][2]=1;vis[2][7]=vis[7][2]=1;vis[3][4]=vis[4][3]=1;vis[3][7]=vis[7][3]=1;vis[4][5]=vis[5][4]=1;vis[5][7]=vis[7][5]=1;vis[5][6]=vis[6][5]=1;vis[6][7]=vis[7][6]=1;for (i=1;i<128;i++)			//用7位二进制表示各段选择情况{int j=i, k=1;memset(ans,0,sizeof(ans));while(j)						//求出i的二进制的每一位,存进数组{ans[k++]=j%2;j/=2;}if (check()) num++;}printf("%d\n",num);return 0;
}

14省8-蚂蚁感冒


https://vijos.org/d/gadflycq/contest/601bf6daf413621b7b360286/5ab51f74d3d8a13712243385
思维题。。
【参考思路】:

1、蚂蚁碰撞之后掉头和不掉头穿过,从效果上来看是一样的。因为速度一样,都是从一只感染变为两只感染。
2、最终感染数量 = 位于感染源左边向右走的个数 + 位于感染源右边向左走的个数 + 1(感染源本身)
3、极端情况下感染源行进方向没有相对行进的蚂蚁,那么最终只有感染源自己被感染。
考试时写的代码,分数是75,错误原因是for循环的边界写错了。
75分代码

#include <bits/stdc++.h>using namespace std;struct mymayi{int z,id;bool zf;}m[53];
bool cmp(mymayi a,mymayi b){return a.z<b.z;}
int main()
{     int n,e,input;cin>>n;for(e=0;e<=n-1;e++){scanf("%d",&input);m[e].z=abs(input),m[e].id=e,m[e].zf=input>0?1:0;}sort(m,m+n,cmp);int tag,left=0,right=0,ans=0;//左边for(int i=0;i<=n-1;i++ ){if(m[i].id==0){tag=i;break;}if(m[i].zf) left++;//1向右走}//右边for(int i=tag;i<=n-1;i++){if(!m[i].zf) right++;//0向左走}if(m[tag].zf&&right==0||!m[tag].zf&&left==0) ans=1;else ans=left+right+1;printf("%d",ans);return 0;}

100分代码:

#include <bits/stdc++.h>using namespace std;struct mymayi{int z,id;bool zf;}m[53];
bool cmp(mymayi a,mymayi b){return a.z<b.z;}
int main()
{     int n,e,input;cin>>n;for(e=0;e<=n-1;e++){scanf("%d",&input);m[e].z=abs(input),m[e].id=e,m[e].zf=(input>0)?1:0;}sort(m,m+n,cmp);int tag,left=0,right=0,ans=0;//左边for(int i=0;i<=n-1;i++ ){if(m[i].id==0){tag=i;break;}if(m[i].zf) left++;//1向右走}//右边for(int i=n-1;i>tag;i--){if(!m[i].zf) right++;//0向左走}if((m[tag].zf&&right==0 )|| ((!m[tag].zf)&&left==0)) ans=1;else ans=left+right+1;printf("%d",ans);return 0;}

这道题思路很重要,如果当时思考感染掉头,考虑之后的情况,那就是思路死胡同了,蚂蚁碰撞之后掉头和不掉头穿过,从效果上来看是一样的,这个要看出。考试时如果思路陷入了死胡同,那很有可能你思路错了,及时改变思路!!!

14省9-地宫取宝

https://vijos.org/d/gadflycq/p/5ab5210ad3d8a1371224338b
X 国王有一个地宫宝库。是 n × m 个格子的矩阵。每个格子放一件宝贝。每个宝贝贴着价值标签。

地宫的入口在左上角,出口在右下角。

小明被带到地宫的入口,国王要求他只能向右或向下行走。

走过某个格子时,如果那个格子中的宝贝价值比小明手中任意宝贝价值都大,小明就可以拿起它(当然,也可以不拿)。

当小明走到出口时,如果他手中的宝贝恰好是k件,则这些宝贝就可以送给小明。

请你帮小明算一算,在给定的局面下,他有多少种不同的行动方案能获得这k件宝贝。

输入
输入一行3个整数,用空格分开:n m k (1<=n,m<=50, 1<=k<=12)

接下来有 n 行数据,每行有 m 个整数 Ci (0<=Ci<=12)代表这个格子上的宝物的价值

输出
要求输出一个整数,表示正好取k个宝贝的行动方案数。该数字可能很大,输出它对 1000000007 取模的结果。
考试时代码:
14分代码

#include <bits/stdc++.h>using namespace std;
int a[55][55];
int n,m,cnt,k;
int ans=0,price;
void dfs(int i,int j,int ma,int cnt){if(cnt>k) return ;if(i==n||j==m)  return ;price=a[i][j];if(i==n-1&&j==m-1){if(cnt==k||(cnt==k-1&&price>ma)){ans++;ans%=1000000007;}return ;}if(price>ma){dfs(i+1,j,price,cnt+1);dfs(i,j+1,price,cnt+1);}dfs(i+1,j,ma,cnt);dfs(i,j+1,ma,cnt);
}
int main()
{cin>>n>>m>>k;for(int i=0;i<=n-1;i++)for(int j=0;j<=m-1;j++){scanf("%d",&a[i][j]);}dfs(0,0,-1,0);printf("%d",ans);return 0;}

数据规格是50*50递归的话容易timeout。
在这里插入图片描述
42分代码:

#include <bits/stdc++.h>
using namespace std;
int n,m,k,a[50][50];
long long ans=0;
void dfs(int x,int y,int ma,int cnt){int cur=a[x][y];if(x==n||y==m) return ;if(x==n-1&&y==m-1){if(cnt==k) ans++;if(cnt==k-1&&cur>ma) ans++;}if(cur>ma){//可取dfs(x+1,y,cur,cnt+1);dfs(x,y+1,cur,cnt+1);}else{dfs(x+1,y,ma,cnt);dfs(x,y+1,ma,cnt);}}
int main(){cin>>n>>m>>k;for(int i=0;i<=n-1;i++)for(int j=0;j<=m-1;j++)scanf("%d",&a[i][j]);dfs(0,0,-1,0);printf("%lld",ans);
return 0;}

超时要看能不能变成贪心;是不是可以改成动态规划,用递推方式来做;是否有重复子问题。这个是有交叉的重复子问题的,重复子问题就是dfs里面的参数相同。
这个题改成记忆性递归。

#include <bits/stdc++.h>
using namespace std;
#define mod 1000000007;
int n,m,k,a[50][50],cache[50][50][14][13];long long dfs(int x,int y,int ma,int cnt){long long ans=0;int cur=a[x][y];if(cache[x][y][ma+1][cnt]!=-1) return cache[x][y][ma+1][cnt];if(x==n||y==m||cnt>k) return 0;if(x==n-1&&y==m-1){if(cnt==k) ans++;if(cnt==k-1&&cur>ma) ans++;}if(cur>ma){//可取ans+=dfs(x+1,y,cur,cnt+1);ans+=dfs(x,y+1,cur,cnt+1);}ans+=dfs(x+1,y,ma,cnt);ans+=dfs(x,y+1,ma,cnt);cache[x][y][ma+1][cnt]=ans%mod;return ans%mod;}
int main(){cin>>n>>m>>k;for(int i=0;i<=n-1;i++)for(int j=0;j<=m-1;j++)scanf("%d",&a[i][j]);memset(cache,-1,sizeof(cache));//cache的初始化值要和ans可能的值避开,取-1可行printf("%lld",dfs(0,0,-1,0) );
return 0;}

13省9-带分数

https://vijos.org/d/gadflycq/contest/601bf6daf413621b7b360286/5a98cd10d3d8a1371223dbec
100 可以表示为带分数的形式:100 = 3 + 69258 / 714。
还可以表示为:100 = 82 + 3546 / 197。
注意特征:带分数中,数字1~9分别出现且只出现一次(不包含0)。
类似这样的带分数,100 有 11 种表示法。
输入格式
从标准输入读入一个正整数N (N<1000*1000)
输出格式
程序输出该数字用数码1~9不重复不遗漏地组成带分数表示的全部种数。
注意:不要求输出每个表示,只统计有多少表示法!
思路:
我们可以把问题简化为下面的表达式:
num = left + up / down
我们的思想是:
先遍历left,再遍历down,两层for循环就可以解决;
找出符合条件(left、up、down为1~9不重复的9个数字组成)。
生成1~9的全排列
解法二:dfs

#include<iostream>
#include<cstring>
using namespace std;int N,ans,digit,flag,full[9];void div(int m)
{while(m){if(m%10!=0)full[m%10-1]=1;m/=10;digit++;}
}bool check(int *f)
{int j;for(j=0;j<9;j++)if(!f[j])return false;return true;
}void  DFS(int a,int b,int c)
{digit=0;flag=0;div(a);div(b);div(c);if(digit>9){memset(full,0,sizeof(full));return ;}if(check(full)){ans++;memset(full,0,sizeof(full));}else memset(full,0,sizeof(full));DFS(a,(c+1)*b/c,c+1);return ;
}int main()
{int i;while(cin>>N){ans=0;memset(full,0,sizeof(full));for(i=2;i<N-1;i++)DFS(i,N-i,1);cout<<ans<<endl;}return 0;
}

这篇关于调试小记1既约分数2 蛇形填数3跑步锻炼4七段码5蚂蚁感冒6地宫取宝7带分数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/379977

相关文章

C++中实现调试日志输出

《C++中实现调试日志输出》在C++编程中,调试日志对于定位问题和优化代码至关重要,本文将介绍几种常用的调试日志输出方法,并教你如何在日志中添加时间戳,希望对大家有所帮助... 目录1. 使用 #ifdef _DEBUG 宏2. 加入时间戳:精确到毫秒3.Windows 和 MFC 中的调试日志方法MFC

ASIO网络调试助手之一:简介

多年前,写过几篇《Boost.Asio C++网络编程》的学习文章,一直没机会实践。最近项目中用到了Asio,于是抽空写了个网络调试助手。 开发环境: Win10 Qt5.12.6 + Asio(standalone) + spdlog 支持协议: UDP + TCP Client + TCP Server 独立的Asio(http://www.think-async.com)只包含了头文件,不依

如何在Visual Studio中调试.NET源码

今天偶然在看别人代码时,发现在他的代码里使用了Any判断List<T>是否为空。 我一般的做法是先判断是否为null,再判断Count。 看了一下Count的源码如下: 1 [__DynamicallyInvokable]2 public int Count3 {4 [__DynamicallyInvokable]5 get

poj 2976 分数规划二分贪心(部分对总体的贡献度) poj 3111

poj 2976: 题意: 在n场考试中,每场考试共有b题,答对的题目有a题。 允许去掉k场考试,求能达到的最高正确率是多少。 解析: 假设已知准确率为x,则每场考试对于准确率的贡献值为: a - b * x,将贡献值大的排序排在前面舍弃掉后k个。 然后二分x就行了。 代码: #include <iostream>#include <cstdio>#incl

计算机毕业设计 大学志愿填报系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点赞 👍 收藏 ⭐评论 📝 🍅 文末获取源码联系 👇🏻 精彩专栏推荐订阅 👇🏻 不然下次找不到哟~Java毕业设计项目~热门选题推荐《1000套》 目录 1.技术选型 2.开发工具 3.功能

ZOJ Monthly, August 2014小记

最近太忙太忙,只能抽时间写几道简单题。不过我倒是明白要想水平提高不看题解是最好的了。 A  我只能死找规律了,无法证明 int a[50002][2] ;vector< vector<int> > gmax , gmin ;int main(){int n , i , j , k , cmax , cmin ;while(cin>>n){/* g

Codeforces Round #261 (Div. 2)小记

A  XX注意最后输出满足条件,我也不知道为什么写的这么长。 #define X first#define Y secondvector<pair<int , int> > a ;int can(pair<int , int> c){return -1000 <= c.X && c.X <= 1000&& -1000 <= c.Y && c.Y <= 1000 ;}int m

2014 Multi-University Training Contest 8小记

1002 计算几何 最大的速度才可能拥有无限的面积。 最大的速度的点 求凸包, 凸包上的点( 注意不是端点 ) 才拥有无限的面积 注意 :  凸包上如果有重点则不满足。 另外最大的速度为0也不行的。 int cmp(double x){if(fabs(x) < 1e-8) return 0 ;if(x > 0) return 1 ;return -1 ;}struct poin

2014 Multi-University Training Contest 7小记

1003   数学 , 先暴力再解方程。 在b进制下是个2 , 3 位数的 大概是10000进制以上 。这部分解方程 2-10000 直接暴力 typedef long long LL ;LL n ;int ok(int b){LL m = n ;int c ;while(m){c = m % b ;if(c == 3 || c == 4 || c == 5 ||