eg:掉分場,D題馬拉車常數爆炸了一直tle,賽後換了種寫法過了。
A
題意:構造出一個長度爲n的數字,使其不爲任意數位的數字的倍數。
題解:若干個2最後加個9,9的倍數是各個數位的數字之和爲9的倍數,如果前面若干個2之和是9的倍數的話換個2成4就好了。
#include "stdio.h"
#include "string.h"
#include "string"
#include "iostream"
#include "algorithm"
#include "vector"
#include "queue"
#include "math.h"
#include "map"
#include "stack"
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
const ll mod=998244353;
const int inf=0x3f3f3f3f;
const ll INF=1e12;
const double eps=1e-6;
int main(){
int T;
scanf("%d",&T);
while(T--){
int x;
scanf("%d",&x);
if(x==1)puts("-1");
else{
int y=(x-1)*2;
if(y%9==0){
for(int i=1;i<x-1;i++)printf("2");
puts("49");
}else {
for(int i=1;i<x;i++)printf("2");
puts("9");
}
}
}
return 0;
}
B
題意:給出一個長度爲n的數組b和x,對於每一個i都有,,求原數組a。
題解:On反推就行了,比A簡單
#include "stdio.h"
#include "string.h"
#include "string"
#include "iostream"
#include "algorithm"
#include "vector"
#include "queue"
#include "math.h"
#include "map"
#include "stack"
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
const ll mod=998244353;
const int inf=0x3f3f3f3f;
const ll INF=1e12;
const double eps=1e-6;
int n,a[maxn],b[maxn];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&b[i]);
int x=0;
a[1]=b[1];
for(int i=2;i<=n;i++){
x=max(x,a[i-1]);
a[i]=b[i]+x;
}
for(int i=1;i<n;i++)printf("%d ",a[i]);
printf("%d\n",a[n]);
return 0;
}
C
題意:給出長度爲n的排列,將其劃分爲k組,求每組的最大值之和和能求到該種最大值的劃分數。
題解:答案是顯然的從大到小取k個數,其和就是第一個問題的答案。劃分的種類數就是每個位置差的乘積。
反思:忘開longlong wa了一發,忘取模wa了一發,真傻
#include "stdio.h"
#include "string.h"
#include "string"
#include "iostream"
#include "algorithm"
#include "vector"
#include "queue"
#include "math.h"
#include "map"
#include "stack"
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
const ll mod=998244353;
const int inf=0x3f3f3f3f;
const ll INF=1e12;
const double eps=1e-6;
string s,ans;
int n,k,b[maxn];
struct arr{
int val,rk;
}a[maxn];
bool cmp(arr a,arr b){
return a.val<b.val;
}
int main(){
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)scanf("%d",&a[i].val),a[i].rk=i;
ll ans=0;
sort(a+1,a+1+n,cmp);
for(int i=n,j=1;i>=1,j<=k;i--,j++)
ans=ans+1ll*a[i].val;
for(int i=n,j=1;i>=1,j<=k;i--,j++)
b[j]=a[i].rk;
sort(b+1,b+1+k);
ll cnt=1;
for(int i=2;i<=k;i++)
cnt=cnt*(1ll*abs(b[i]-b[i-1]))%mod;
printf("%lld %lld\n",ans,cnt);
return 0;
}
D
題意:給定字符串s,找一個前綴和一個後綴使其拼接起來爲一個迴文串。D1長度爲5000 D2長度爲1000000
題解:D1暴力亂搞即可,D2哈希 馬拉車 迴文自動機也可以。將問題拆成兩步,第一步原串左右找相同部分,假設找完之後左右指針分別爲L和R,那麼就從L和R各找一個迴文串,取一個最長的即爲答案。
D1廢物暴力代碼
#include "stdio.h"
#include "string.h"
#include "string"
#include "iostream"
#include "algorithm"
#include "vector"
#include "queue"
#include "math.h"
#include "map"
#include "stack"
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
const ll mod=998244353;
const int inf=0x3f3f3f3f;
const ll INF=1e12;
const double eps=1e-6;
string s,ans;
bool check(string t){
int l=0,r=t.length()-1;
while(l<r){
if(t[l]==t[r])l++,r--;
else return false;
}
return true;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
cin>>s;ans.clear();
string px,sx;
px.clear();sx.clear();
int len=s.length();
if(len==1)cout<<s<<endl;
else{
int l=0,r=len-1;
while(l<r){
px.push_back(s[l]);
sx.push_back(s[r]);
if(px==sx)l++,r--;
else break;
}
if(px[px.length()-1]!=sx[sx.length()-1])px.pop_back(),sx.pop_back();
if(l>r){
ans=px;
reverse(sx.begin(), sx.end());
ans=ans+sx;
}else{
string sum,num;sum.clear();num.clear();
for(int i=l;i<=r;i++){
sum.push_back(s[i]);
if(check(sum)){
if(sum.length()>num.length())num=sum;
}
}
sum.clear();
for(int i=r;i>=l;i--){
sum.push_back(s[i]);
if(check(sum)){
if(sum.length()>num.length())num=sum;
}
}
ans=px;
ans=ans+num;
reverse(sx.begin(), sx.end());
ans=ans+sx;
}
cout<<ans<<endl;
}
}
return 0;
}
D2代碼
#include "stdio.h"
#include "string.h"
#include "string"
#include "iostream"
#include "algorithm"
#include "vector"
#include "queue"
#include "math.h"
#include "map"
#include "stack"
using namespace std;
typedef long long ll;
const int maxn=1e6+10;
const ll mod=998244353;
const int inf=0x3f3f3f3f;
const ll INF=1e12;
const double eps=1e-6;
char s[2*maxn],ss[maxn];
int n,p[2*maxn];
void manacher(){
for(int i=n*2;i>1;i--){
if(i&1)s[i]='@';
else s[i]=s[i>>1];
}
s[1]=s[2*n+1]='#';
n=2*n+1;
p[1]=1;
int mx=1,id=1;
for(int i=2;i<=n;i++){
if(i<=mx){
p[i]=min(p[2*id-i],mx-i+1);
}
else p[i]=1;
while(i+p[i]<=n&&i-p[i]>=1&&s[i+p[i]]==s[i-p[i]])p[i]++;
if(mx<i+p[i]-1){
mx=i+p[i]-1;
id=i;
}
}
}
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%s",ss+1);
n=strlen(ss+1);
int m=n;
int l=1;
while(l<=n/2&&ss[l]==ss[n-l+1])l++;
if(l*2>n){
printf("%s\n",ss+1);
continue;
}
for(int i=1;i<=n-2*(l-1);i++)s[i]=ss[l+i-1];
n-=2*(l-1);
s[n+1]='\0';
manacher();
int pos=0;
for(int i=1;i<=n;i++){
if(p[i]==i-1&&p[i]>p[pos]) pos=i;
if(p[i]==n-i&&p[i]>p[pos]) pos=i;
}
for(int i=1;i<l;i++) putchar(ss[i]);
for(int i=pos-p[pos]+1;i<=pos+p[pos]-1;i++)
if(s[i]>='a'&&s[i]<='z') putchar(s[i]);
for(int i=m-l+2;i<=m;i++) putchar(ss[i]);
putchar('\n');
}
return 0;
}