NOIP2000提高组。
都写过还一堆错,蒟蒻。
A.进制转换,没考虑0。90分。
B.乘积最大。因为写高精乘时没有判0.90分。
C.单词接龙。以为最会T掉的题,结果A了。
D.方格取数。应该从0开始循环,而非1,丢掉50分。
A
#include <bits/stdc++.h>
using namespace std;
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x*f;
}
int n,k,ans[105];
char id[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J'};
int main(){//-3/-2=1...-1,3/-2=-1...1
// freopen("a.in","r",stdin);
n=read();k=read();int x=n;
while(x){
int a=x/k,b=x-a*k;
if(b<0) b-=k,a+=1;
ans[++ans[0]]=b;x=a;
}printf("%d=",n);
if(!ans[0]) printf("0");
for(int i=ans[0];i>=1;--i) putchar(id[ans[i]]);
printf("(base%d)",k);
return 0;
}
B
#include <bits/stdc++.h>
using namespace std;
#define N 60
#define ll long long
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x*f;
}
int n,kk;
char s[N];
struct bigint{
int a[N],n;
bigint(){memset(a,0,sizeof(a));n=0;}
friend bigint operator*(bigint a,bigint b){
bigint res;if(!a.n||!b.n) return res;//注意和0相乘要特判
res.n=a.n+b.n-1;
for(int i=1;i<=a.n;++i)
for(int j=1;j<=b.n;++j)
res.a[i+j-1]+=a.a[i]*b.a[j];
for(int i=1;i<=res.n;++i)
res.a[i+1]+=res.a[i]/10,res.a[i]%=10;
while(res.a[res.n+1]) res.n++,res.a[res.n+1]+=res.a[res.n]/10,res.a[res.n]%=10;
return res;
}
friend bool operator<(bigint a,bigint b){
if(a.n<b.n) return 1;
if(a.n>b.n) return 0;
for(int i=a.n;i>=1;--i){
if(a.a[i]<b.a[i]) return 1;
if(a.a[i]>b.a[i]) return 0;
}return 0;
}
};
void solve1(){
ll a[N][N];memset(a,0,sizeof(a));
ll dp[N][10];memset(dp,0,sizeof(dp));
for(int i=1;i<=n;++i)
for(int j=i;j<=n;++j)
a[i][j]=a[i][j-1]*10+s[j]-'0';
for(int i=1;i<=n;++i) dp[i][0]=a[1][i];
for(int k=1;k<=kk;++k)
for(int i=k+1;i<=n;++i)
for(int j=k;j<i;++j)
dp[i][k]=max(dp[i][k],dp[j][k-1]*a[j+1][i]);
printf("%lld\n",dp[n][kk]);
}
void solve2(){
bigint a[N][N];bigint dp[N][10];
for(int i=1;i<=n;++i)
for(int j=i;j<=n;++j){
for(int k=1;k<=j-i+1;++k)
a[i][j].a[k]=s[j-k+1]-'0';
a[i][j].n=j-i+1;while(a[i][j].n>0&&!a[i][j].a[a[i][j].n]) a[i][j].n--;
}
for(int i=1;i<=n;++i) dp[i][0]=a[1][i];
for(int k=1;k<=kk;++k)
for(int i=k+1;i<=n;++i)
for(int j=k;j<i;++j)
if(dp[i][k]<dp[j][k-1]*a[j+1][i]) dp[i][k]=dp[j][k-1]*a[j+1][i];
for(int i=dp[n][kk].n;i>=1;--i)
printf("%d",dp[n][kk].a[i]);
}
int main(){
// freopen("a.in","r",stdin);
n=read();kk=read();scanf("%s",s+1);
if(n<=15) solve1();
else solve2();
return 0;
}
C
#include <bits/stdc++.h>
using namespace std;
#define N 30
int n,ans=0,cnt[N];
char s[N][1000],res[3000000];
bool jud(char a[],char b[]){//判断a是否包含在b的前面
int la=strlen(a+1),lb=strlen(b+1);
if(la>=lb) return 0;
for(int i=1;i<=la;++i)
if(a[i]!=b[i]) return 0;
return 1;
}
void dfs(int now,int len){
ans=max(ans,len);
for(int i=now;i<=len;++i){
char s1[3000];memset(s1,0,sizeof(s1));
for(int j=i;j<=len;++j) s1[j-i+1]=res[j];
for(int j=1;j<=n;++j)
if(cnt[j]<=1&&jud(s1,s[j])){
cnt[j]++;for(int k=1;k<=strlen(s[j]+1);++k) res[i+k-1]=s[j][k];
dfs(i+1,i+strlen(s[j]+1)-1);
cnt[j]--;
}
}
}
int main(){
// freopen("a.in","r",stdin);
scanf("%d",&n);
for(int i=1;i<=n;++i) scanf("%s",s[i]+1);
scanf("%s",res+1);
dfs(1,1);
printf("%d\n",ans);
return 0;
}
D
#include <bits/stdc++.h>
using namespace std;
#define N 15
#define ll long long
inline ll read(){
ll x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x*f;
}
int n;
ll mp[N][N],dp[N<<1][N][N];//dp[k][i][j],共走k步,1向下i步,2向下j步
int main(){
// freopen("a.in","r",stdin);
n=read();
while(1){
int x=read(),y=read(),val=read();
if(x==0) break;
mp[x][y]=val;
}dp[0][0][0]=mp[1][1];
for(int k=1;k<=n-1<<1;++k)
for(int i=0;i<=n-1;++i)//可以向下走0步!!!
for(int j=0;j<=n-1;++j){
if(i>k||j>k||k-i>n-1||k-j>n-1) continue;
dp[k][i][j]=max(max(dp[k-1][i][j],dp[k-1][i-1][j]),max(dp[k-1][i-1][j-1],dp[k-1][i][j-1]));
dp[k][i][j]+=mp[i+1][k-i+1];
if(i!=j) dp[k][i][j]+=mp[j+1][k-j+1];
}
printf("%lld\n",dp[n-1<<1][n-1][n-1]);
return 0;
}