思路:
使用 dfs 算法,创建一个数组存当前已经找到的数字。
深度优先搜索代码实现:传入的量为现在找的是第几个数,第一次传入的是一,表示现在找的是第一个数,当传入的数减一等于 mmm 时输出。
输出函数实现:循环定义的 iii 表示当前已经找到的数字的数组的下标,如果你下标是从零开始存的就从零历遍到 m−1m-1m−1,如果是从一开始存的就从 111 历遍到 mmm,注意不要忘了最后换行。
因为题目中要求字典序较小的排在前面,所以我们就不定义标记数组了,下一次搜索就直接从上一个数加一开始。
完整代码:
#include<bits/stdc++.h>using namespace std;#define LL long long#define itn int#define ull unsigned long longull n,m;ull sc[30];// 存现在找到的数字void print(){// 输出 for(int i=1;i<=m;i++)cout<<sc[i]<<" "; cout<&l ...
思路:
使用前缀和,考虑到输入的询问范围可能会有 lll 相同,所以先用一个结构体把输入的 lll 和 rrr 和输入的顺序存起来,然后进行排序哪个左端点更小,如果同时左端点相同,那么比较哪个右端点更小。
在 lll 相等时,我们可以直接按照上一个的答案往下搜这样重复的部分就不用重复计算历遍了。
为什么可以直接按照上一个的答案往下搜,因为我们在一开始排过序,只要这个结构体排完序后在前一个结构体后面,并且 lll 相同,那么后面的结构体的 rrr 一定大于等于前面的结构体的 rrr,所以可以直接按照上一个的答案往下搜。
当 lll 不相等时,就正常地直接历遍,然后存答案就可以了。
完整代码:
#include<bits/stdc++.h>using namespace std;#define ull unsigned long long#define LL long longull tamp;const int MAXN=10001;const int MAXQ=1000001;ull n,q;ull sum[MAXN];ull a[100010];struct nod ...
思路:
因为只有通过删除一个字符,或插入一个字符,或修改一个字符变成另一个字符串才是相似的,所以我们可以分成五种情况。
第一种情况,如果第一个字符串和第二个字符串是相同的,那么这两个字符串是相似的,代码如下。
if(a==b){// 特判如果 a 与 b 相同的情况 cout<<"similar\n";continue;}
第二种情况,如果第一个字符串的长度等于第二个字符串的长度且两个字符串不相同,如果它们是相似的,那么只能是修改一个字符出来的,两个字符串之间至少有第一个字符串的长度减一个字符是相同的,且位置相同,代码如下。
if(a.size()==b.size()){// a 的长度与 b 的长度相同 for(int i=0;i<a.size();i++){ if(a[i]==b[i])cnt++;// 都用 i 因为要在同一个位置 } if(cnt+1==a.size()||cnt==a.size()){// 至少有 a.size()-1 个字符相同且在同一个位置 co ...
思路:
先写出暴力的搜索,然后改为记忆化搜索。
暴力的搜索就是暴力向下搜 nnn 减去 aaa 和 nnn 减去 bbb 的游戏操作序列的总数,暴力搜索代码如下。
long long dfs(long long x){ if(x<=c)return 1; return (dfs(x-a)%mod+dfs(x-b)%mod)%mod;}
然后改为记忆化搜索,定义一个数组存结果,如果现在搜索的这个数已经被搜索过了就自己访问数组,如果没有就先搜索,搜索完后赋值,这样就可以防止重复地搜索一个数,记忆化搜索代码如下。
long long dfs(long long x){ if(x<=c)return 1; if(an[x]!=0)return an[x];// 如果有值直接返回 return an[x]=(dfs(x-a)%mod+dfs(x-b)%mod)%mod;// 如果没有进行搜索并赋值}
完整代码:
#include<bits/stdc++.h>using namespace std;long long an[20 ...
思路:
考虑到 nnn 的最大值只有九,所以可以使用 dfs 算法枚举组合方案,把每一头牛的放置顺序存入一个数组中,当把所有的牛都放好后,算出需要的牛棚,最后输出最小值就可以了。
如何算出需要的牛棚,先画张图。
观察这张图,可以分四种情况。
第一种情况,上一头牛的 bbb 大于现在这头牛的 aaa,那么距离是上一头牛的 bbb,如下图。
第二种情况,上一头牛的 bbb 等于现在这头牛的 aaa,那么这两个数都可以是距离,如下图。
第三种情况,上一头牛的 bbb 小于现在这头牛的 aaa,那么距离是这头牛的 aaa,如下图。
第四种情况,没有上一头牛,也就是第一头牛,没有距离,循环直接从第二个放入牛的开始,如下图。
通过上述分析可以看出,距离是上一头牛的 bbb 与这头牛的 aaa 中的最大值。
需要注意的是求完距离后要考虑这一头牛也需要一个牛棚,所以每次求出距离后还要加一才可以算出需要的牛棚,要提前处理第一头牛,可以直接将求需要的牛棚的变量赋值为一。
完整代码带注释:
代码与思路完全相同。
#include<bits/stdc++.h>using names ...
思路:
定义一个数组存这个数最大的质因数。
如何存,枚举每一个小于 nnn 的质数,再枚举它的倍数,但是在枚举倍数时要注意如果第二个数字大于了第一个数字且第二个数字是质数那么先跳过,且第一个数字乘第二个数字要是大于 nnn 那么退出这一层循环写进判断条件里,代码如下。
for(long long i=2;i<=n;i++){ if(zs(i))//注意 i 要是质数 for(long long j=1;j*i<=n;j++){//枚举 i 的倍数 if(j>i&&zs(j))continue;// 如果 j 大于 i 且 j 是质数 那么说明 i*j 这个数的最大质因数不是 i 直接跳过后面再赋值 bj[j*i]=i; //cout<<i*j<<"\n";// 测试 } else continue;//i 不是质数跳过 }
标记好了后,定义一个存的变量变量赋值为一,因为虽然一没有质因数但是还是要加上,然后枚举从二到 nnn 中有多少个的最大质因数 ...
思路:
规律:观察后发现答案是每种邮票的张数除以现在的人数后省去小数部分后再次乘以人数。
每种邮票的张数除以现在的人数后省去小数部分就是可以分成几组,组不能是小数,因为题中说申请人都必须从该城市获得相同数量的邮票所以不能分开。
再乘以人数就是求分出了几张邮票。
一开始想用桶但发现数据太大了开不了数组,所以用了 map 但是用了 map 后发现不能满分于是观察了下发现只要有一个的邮票发出总和为零时,后面的也都是零,这样过后发现还是不可以满分,再次观察题目发现是不需要排序的,所以把 map 改成 unordered_map 就这样了吗,没有,再次观察可以发现当一个邮票的张数已经小于现在的人数了,那么不管怎么样,后面都不可以让答案增加了,所以直接删去,这样就可以了。
代码:
#include<bits/stdc++.h>using namespace std;unordered_map<int,int>mp;int n;int main(){ ios::sync_with_stdio(0); cin.tie(0);cout.tie(0); cin> ...
思路:
使用结构体快排,自己写判断函数,按照题目给出的进行判断,判断后历遍一次结构体数组,把学生的排名赋值,然后按照输入的顺序再排序一次最后输出就可以了。
如何赋值排名,如果和上一个人的排名是相同的就赋值为上一个人的排名,如果不是直接赋值为 iii。
代码:
// 以下代码与思路完全相同 // 本代码已经提交测试并且已经 AC #include<bits/stdc++.h>using namespace std;int n;struct node{ long long sum/* 总和 */,chinese/* 语文 */,math/* 数学 */,english/*english 可以不定义在结构体里 */; long long pm/* 排名 */,bh/* 编号 */;}stud[10002]; bool cmp(node x,node y){// 排序排名降序 if(x.sum!=y.sum)return x.sum>y.sum;// 判断总分 else{// 如果总分相同 if(x.chinese+x.ma ...
思路:
先通过此程序列出部分立方根向下取整的情况。
#include<bits/stdc++.h>using namespace std;long long s[20000000];long long jia(long long x,long long y){ long long sum=0; for(int i=x+1;i<=y;i++)sum+=cbrt(i); return sum;}int main(){ long long x,y=0; long long last=0,las=0; for(int i=1;i<=1e6;i++){ s[i]=s[i-1]+cbrt(i); if(s[i]-s[i-1]!=last)cout<<i<<" "<<s[i]<<"\n",last=s[i]-s[i-1]; } return 0;}
可以发现每次当 iii 为某数的立方时,立方根向下取整的结果会增加一 ...
思路:
按照题目模拟,题目要求我们判断加法等式是否成立。
那么如何输入,可以先输入一个数字,再输入字符,再输入数字,再输入字符,再输入数字,然后判断第一个数字加第二个数字是否等于第三个数字就可以了。
代码:
#include<bits/stdc++.h>using namespace std;int T,a,b,c;int main(){ cin>>T;char fuh; while(T--){ cin>>a>>fuh>>b>>fuh>>c; if(a+b!=c)cout<<"Wrong!\n"; else cout<<"Right!\n"; } return 0;}