codeforcesA~C
A.Forbidden Integer
题意:t组输入,每组输入n,k,x;求解用1-k中的数但不包括x来表示n,如果可以则输出,不可以则打印NO.
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 100010 + 10;
int a[N];
signed main() {
int t;
cin>>t;
while(t--){
int n,k,x;
cin>>n>>k>>x;
if(x!=1){
cout<<"YES\n"<<n<<"\n";
while(n--) cout<<1<<" ";
cout<<endl;
}
else{
if(n%2==1&&k==2) cout<<"NO\n";
else if(n%2==0&&k>=2){
int x=n/2;
cout<<"YES\n";
cout<<x<<endl;
while(x--) cout<<2<<" ";
cout<<endl;
}
else if(n%2==1&&k>=3){
cout<<"YES\n";
int x=n/2;
cout<<x<<endl;
x--;
while(x--) cout<<2<<" ";
cout<<3<<endl;
}
else cout<<"NO\n";
}
}
return 0;
}
题目说有多种解,则知道可以有简便的思想:
1.如果x!=1,则可以全为一
2.若x为1,且是k>=3,则n为偶数便全用2,为奇数则最后一个2为3;
3.若x为1,k==2,为奇数无解,偶数有解,全用2;
4.若x为1,k==1,无解
B.Come Together
题意:三个点,A,B,C求解两个人分别从A到B和C的最短路径中的最长公共路径
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 100010 + 10;
signed main() {
int t;
cin>>t;
while(t--){
int ax,ay,bx,by,cx,cy;
cin>>ax>>ay>>bx>>by>>cx>>cy;
int ans=1;
bx-=ax,by-=ay,cx-=ax,cy-=ay;
if((bx>0)==(cx>0)) ans+=min(abs(bx),abs(cx));
if((by>0)==(cy>0)) ans+=min(abs(by),abs(cy));
cout<<ans<<endl;
}
return 0;
}
画图理解
C.Strong Password
题意:给出s,l,r三个字符串,m是l和r的长度,求解是否有一个新的长为m的字符串x,且li<=xi<=ri,且x不是s的子串。
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 100010 + 10;
signed main() {
int t;
cin>>t;
while(t--){
string s,l,r;
int m;
cin>>s>>m>>l>>r;
int n=s.size();
int net[n+1][10];
for(int i=0;i<10;i++) net[n][i]=n;
for(int i=n-1;i>=0;i--)
{
for(int j=0;j<10;j++)
net[i][j]=net[i+1][j];
net[i][s[i]-'0']=i;
}
int x=-1;
for(int i=0;i<m && x < n;i++)
{
int y=0;
for(int j=l[i]-'0';j<=r[i]-'0';j++)
{
y=max(y,net[x+1][j]);
}
x=y;
}
if(x==n) cout<<"YES\n";
else cout<<"NO\n";
}
return 0;
}
如果我们在找到的字符串中,与s重复部分越前则越容易是s的子串。
所以我们只要找到的x中的字母超出s长度的,或者是s中没有的则视为成功。
所以初始化一个二维数组表示net[i][j],表示在s字符串中的第i位上的j字母的位置。
同时初始化注意,如果第i位上不是j字母,则将后面位置的j字母的位置覆盖过来,用于更好求解。
如果都没有,则初始化为n.
D.Rating System
题意:给出一个数组,寻找一个k使得该数组的前缀和在达到k之后就不能再小于k了
理解:求一个连续子数组和最小,然后在此数组前的前缀和就为所求k值,所以运用前缀和的知识。
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 100010 + 10;
int a[N];
signed main() {
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
int csum=0;
int cmax=0;
int kk=0;
int ans;
for(int i=0;i<n;i++)
{
int a;
cin>>a;
csum+=a;
cmax=max(cmax,csum);
int val=cmax-csum;
if(val>kk){
kk=val;
ans=cmax;
}
}
cout<<ans<<endl;
}
return 0;
}