地址:http://codeforces.com/contest/1326
题意:给定n,输出一个长度为n的数字,满足以下条件:1:>0 2:各个位上不出现0 3:不能整除自己的任意一位。
解析:被这题给坑了一下。想不通我的33......7为什么不行,可能太长的话有被7整除的危险,并不能保证万无一失。所以我们需要一个能保证万无一失的通用方法。一个是2333.....3,或是5333.......3。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; typedef long long ll; const int maxn=1e5+10; int a[maxn]; int main() { int t; cin>>t; while(t--) { int n; cin>>n; if(n==1) cout<<"-1"<<endl; else { cout<<"2"; for(int i=1;i<n;i++) cout<<"3"; cout<<endl; } } }
题意:有点小绕,大致就是我画的这个意思。
很明显,题意中有讲,x1=0固定。则a1=b1,直接规定maxx=a1,用这个maxx来维护数组a[]的i-1之前的最大值。ai=bi+maxx,然后更新maxx=max(maxx,bi+maxx);这个顺序不要错。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; typedef long long ll; const int maxn=2e5+10; ll b[maxn]; ll a[maxn]; int main() { int n; cin>>n; for(int i=1;i<=n;i++) cin>>b[i]; int x; a[1]=b[1]; ll maxx=a[1]; for(int i=2;i<=n;i++) { a[i]=b[i]+maxx; maxx=max(maxx,b[i]+maxx); } for(int i=1;i<=n;i++) { if(i<n) cout<<a[i]<<" "; else cout<<a[i]<<endl; } }
题意:也是绕的一批,我这个英语渣压根就没看懂,靠队友才搞懂。
就是更定一个数量n的数组以及一个k,对这个数组进行分块,{|...|,|...|}k是多少,大括号里面就有几个|...|集合,里面是L,R,均为下标。集合之间不能有重叠,要保证全覆盖数组。可以把每个|...|里的最大值提出来,k个最大值相加,得到一个数。目的是找出这个最大数来,以及可以弄出这个数的分块方式有几种。
解析:既然是k个集合,那么要想保证各个最大值加起来最大,那么就要把前k个大的数做为每个集合里的最大值。以此为基准进行分块操作。再画个图看看:假设k=3
三角号表示分界线可放的地方,是不是还是不明白怎么算?没关系,举个例子:有前k大数 a,b。a与b挨着,那么分界线只能插在a上,1种,i+1-i=1,所以根据这个数目就是它们坐标之差。总之就是,记录前k大数的各个坐标之差,乘起来就好了。记得题意里说结果要mod 998244353
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<map> using namespace std; typedef long long ll; const int maxn=2e5+10; int main() { int n,k; cin>>n>>k; ll ans=1; int idx=-1; int x=0; ll sum=0; for(int i=1;i<=n;i++) { cin>>x; if(x>=n-k+1) { sum+=x; if(idx!=-1) { ans=(ans*(i-idx))%998244353; // cout<<i-idx<<endl; } idx=i; } } cout<<sum<<" "<<ans<<endl; }
题意:给你一个字符串,从中找出一个子序列是字符串前缀与字符串后缀(可为空)拼接成的最长回文子字符串。
解析:首先找前后缀构成的回文:
while(l<r&&s[l]==s[r]) l++,r--;
注意了,这个算出来L是比实际+1,R是比实际-1的。便于下面的找中间最长回文(要它与左前缀相连或者与右后缀相连)。在L-R之间找最长回文,用r2=R,l2=L:分别固定L和R来进行中间r2,l2的滑动寻找回文串:
PS:substr(l,d)返回的是以l下标为开头,长度为d的字符串。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; int check(string &s,int l,int r) { while(l<=r&&s[l]==s[r]) { l++; r--; } return r<l?1:0; //如果r<l了,肯定是回文串了,返回1,否则返回0 } int main() { int t; cin>>t; while(t--) { string s; cin>>s; int len=s.length(); int l=0,r=len-1; while(l<r&&s[l]==s[r]) l++,r--; int l2,r2; for(r2=r;r2>=l;r2--) { if(check(s,l,r2)) { break; } } for(l2=l;l2<=r;l2++) { if(check(s,l2,r)) break; } // cout<<l2<<" "<<r2<<endl; cout<<s.substr(0,l); //L算出来比实际+1的,长度即为L-1-0+1=L; if((r2-l)>(r-l2)) cout<<s.substr(l,r2-l+1); else cout<<s.substr(l2,r-l2+1); cout<<s.substr(r+1)<<endl;//R算出来是比实际-1的,直接是输出r+1到串尾 } }