$NOIP2007$ 题解报告
目录
$Luogu\ P1005$ 矩阵取数游戏$(\ √\ )$
$Luogu\ P1097$ 统计数字$(\ √\ )$
$Luogu\ P1098$ 字符串的展开$(\ √\ )$
$Luogu\ P1099$ 树网的核$(\ √\ )$
$Luogu\ P1005$ 矩阵取数游戏
又是讨厌的高精,我调了好久$QAQ$
设$f[i][j]$表示某一行状态变为$[i,j]$时的最大答案,直接从$f[i-1][j],f[i][j+1]$转移
1 #include<bits/stdc++.h> 2 #define ri register int 3 #define ll long long 4 #define rl register ll 5 #define go(i,a,b) for(ri i=a;i<=b;i++) 6 #define back(i,a,b) for(ri i=a;i>=b;i--) 7 #define g() getchar() 8 #define il inline 9 #define pf printf 10 #define mem(a,b) memset(a,b,sizeof(a)) 11 using namespace std; 12 il int fr(){ 13 ri w=0,q=1;char ch=g(); 14 while(ch<'0'||ch>'9'){if(ch=='-')q=-1;ch=g();} 15 while(ch>='0'&&ch<='9')w=(w<<1)+(w<<3)+ch-'0',ch=g(); 16 return w*q; 17 } 18 const int N=82; 19 struct node{ 20 int s[50]; 21 }f[N][N],c[N],ans; 22 int a[N],n,m; 23 il void Mem(node &x,ri y){go(i,0,40)x.s[i]=y;return;} 24 il node mul(node x,int y){ 25 int len=x.s[0]+3,z=0; 26 node as;Mem(as,0); 27 go(i,1,len){ 28 as.s[i]=x.s[i]*y+z; 29 z=as.s[i]/10;as.s[i]%=10; 30 } 31 while(!as.s[len])len--;as.s[0]=len; 32 return as; 33 } 34 il node add(node x,node y){ 35 int len=0,z=0; 36 node as;Mem(as,0); 37 while(len<x.s[0]||len<y.s[0]){ 38 len++;as.s[len]=x.s[len]+y.s[len]+z; 39 z=as.s[len]/10;as.s[len]%=10; 40 } 41 while(z)as.s[++len]=z,z=as.s[len]/10,as.s[len]%=10; 42 as.s[0]=len;return as; 43 } 44 il node Max(node x,node y){ 45 if(x.s[0]>y.s[0])return x; 46 if(x.s[0]<y.s[0])return y; 47 back(i,x.s[0],1){ 48 if(x.s[i]>y.s[i])return x; 49 if(x.s[i]<y.s[i])return y; 50 } 51 return x; 52 } 53 il void MEM(){go(i,1,m)back(j,m,i)go(k,0,28)f[i][j].s[k]=0;return;} 54 int main(){ 55 freopen("1.in","r",stdin); 56 freopen("1.out","w",stdout); 57 n=fr();m=fr(); 58 c[0].s[0]=1;c[0].s[1]=1; 59 go(i,1,m)c[i]=mul(c[i-1],2); 60 go(n0,1,n){ 61 MEM(); 62 go(i,1,m)a[i]=fr(); 63 go(i,1,m)back(j,m,i){ 64 if(i-1>=1)f[i][j]=Max(f[i][j],add(f[i-1][j],mul(c[m-j+i-1],a[i-1]))); 65 if(j+1<=m)f[i][j]=Max(f[i][j],add(f[i][j+1],mul(c[m-j+i-1],a[j+1]))); 66 } 67 node mx;Mem(mx,0); 68 go(i,1,m){ 69 mx=Max(mx,add(f[i][i],mul(c[m],a[i]))); 70 } 71 ans=add(ans,mx); 72 } 73 if(ans.s[0]==0)puts("0"); 74 back(i,ans.s[0],1)pf("%d",ans.s[i]);puts(""); 75 return 0; 76 }
$Luogu\ P1097$ 统计数字
排序后直接统计即可
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n; 4 long long b[200002]; 5 struct num{ 6 int s,x; 7 }a[10002]; 8 int main(){ 9 int tot=1,i; 10 scanf("%d",&n); 11 for(i=1;i<=n;i++) 12 scanf("%lld",&b[i]); 13 sort(b+1,b+n+1); 14 a[tot].s=b[1],a[tot].x++; 15 for(i=2;i<=n;i++){ 16 if(b[i]!=b[i-1]) a[++tot].s=b[i],a[tot].x++; 17 else a[tot].x++; 18 } 19 for(i=1;i<=tot;i++) 20 printf("%d %d\n",a[i].s,a[i].x); 21 return 0; 22 }
$Luogu\ P1098$ 字符串的展开
非常简单,直接模拟展开即可
1 #include<bits/stdc++.h> 2 using namespace std; 3 char s1[10000],s2[102]; 4 int p1,p2,p3,len=0; 5 bool same(char x,char y){ 6 if(x>='0'&&x<='9'&&y>='0'&&y<='9') return 1; 7 if(x>='a'&&x<='z'&&y>='a'&&y<='z') return 1; 8 return 0; 9 } 10 void work(int i){ 11 int l=len+1,r; 12 if(s2[i]>='0'&&s2[i]<='9'){ 13 if(p1==1||p1==2) 14 for(int j=s2[i]+1;j<s2[i+2];j++) 15 for(int k=1;k<=p2;k++) 16 s1[++len]=j; 17 } 18 else{ 19 if(p1==1) 20 for(int j=s2[i]+1;j<s2[i+2];j++) 21 for(int k=1;k<=p2;k++) 22 s1[++len]=j; 23 if(p1==2) 24 for(int j=s2[i]+1;j<s2[i+2];j++) 25 for(int k=1;k<=p2;k++) 26 s1[++len]=j-32; 27 } 28 if(p1==3) 29 for(int j=s2[i]-'0'+1;j<s2[i+2]-'0';j++) 30 for(int k=1;k<=p2;k++) 31 s1[++len]='*'; 32 r=len; 33 if(p3==1) return ; 34 if(p3==2){ 35 char ss[r+5]; 36 for(int j=l;j<=r;j++) 37 ss[j]=s1[r-j+l]; 38 for(int j=l;j<=r;j++) 39 s1[j]=ss[j]; 40 } 41 return; 42 } 43 int main(){ 44 cin>>p1>>p2>>p3; 45 getchar(); 46 cin>>s2; 47 for(int i=0;i<strlen(s2);i++){ 48 if(s2[i]=='-'){ 49 if(!same(s2[i-1],s2[i+1])||s2[i+1]<=s2[i-1]||s2[i+1]==s2[i-1]+1){ 50 if(s2[i+1]!=s2[i-1]+1) s1[++len]=s2[i]; 51 continue; 52 } 53 work(i-1); 54 } 55 else s1[++len]=s2[i]; 56 } 57 for(int i=1;i<=len;i++) 58 cout<<s1[i]; 59 cout<<endl; 60 return 0; 61 }
$Luogu\ P1099$ 树网的核
这题其实思维不是很难,主要注意细节
先$dfs$求出直径,然后用一个栈维护一下直径上的点,求出题目要求的偏心距即可
1 #include<bits/stdc++.h> 2 #define ri register int 3 #define ll long long 4 #define rl register ll 5 #define go(i,a,b) for(ri i=a;i<=b;i++) 6 #define back(i,a,b) for(ri i=a;i>=b;i--) 7 #define g() getchar() 8 #define il inline 9 #define pf printf 10 #define mem(a,b) memset(a,b,sizeof(a)) 11 #define E(i,x) for(ri i=hd[x];i;i=e[i].nxt) 12 #define t(i) e[i].to 13 using namespace std; 14 il int fr(){ 15 ri w=0,q=1;char ch=g(); 16 while(ch<'0'||ch>'9'){if(ch=='-')q=-1;ch=g();} 17 while(ch>='0'&&ch<='9')w=(w<<1)+(w<<3)+ch-'0',ch=g(); 18 return w*q; 19 } 20 const int N=302; 21 int n,s,d[N][N],hd[N],ed,mx,top,a[N],mn=1e9+7; 22 vector<int> q; 23 struct edge{ 24 int nxt,to,w; 25 }e[N<<1]; 26 bool vis[N]; 27 il void build(ri x,ri y,ri w){e[++ed]=(edge){hd[x],y,w};hd[x]=ed;return;} 28 il void dfs(ri frm,ri x,ri fa){ 29 //cout<<"frm="<<frm<<" x="<<x<<" fa="<<fa<<endl; 30 E(i,x){ 31 if(t(i)==fa)continue; 32 d[x][t(i)]=e[i].w; 33 d[frm][t(i)]=e[i].w+d[frm][x]; 34 dfs(frm,t(i),x); 35 } 36 return; 37 } 38 il void sol(){ 39 go(tp,1,top){ 40 ri nw=tp,Max=0;vis[a[tp]]=1; 41 while(nw<top&&d[a[tp]][a[nw+1]]<=s)nw++,vis[a[nw]]=1; 42 go(i,1,n){ 43 ri as=1e9+7; 44 if(vis[i])continue; 45 go(j,tp,nw){ 46 as=min(as,d[a[j]][i]); 47 } 48 Max=max(Max,as); 49 } 50 mn=min(mn,Max); 51 vis[a[tp]]=0; 52 } 53 return; 54 } 55 il void work(ri frm,ri x,ri fa){ 56 //cout<<frm<<" "<<x<<" "<<fa<<endl; 57 a[++top]=x; 58 if(d[frm][x]==mx){sol();top--;return;} 59 E(i,x){ 60 if(t(i)==fa)continue; 61 work(frm,t(i),x); 62 } 63 top--;return; 64 } 65 int main(){ 66 //freopen("1.in","r",stdin); 67 //freopen("1.out","w",stdout); 68 n=fr();s=fr(); 69 go(i,1,n-1){ 70 ri x=fr(),y=fr(),w=fr(); 71 build(x,y,w);build(y,x,w); 72 } 73 go(i,1,n)dfs(i,i,0); 74 go(i,1,n-1)go(j,i+1,n){ 75 //cout<<mx<<endl; 76 if(d[i][j]>mx){q.clear();q.push_back(i),mx=d[i][j];} 77 else if(d[i][j]==mx&&q[q.size()-1]!=i)q.push_back(i); 78 } 79 ri siz=q.size(); 80 go(i,0,siz-1)work(q[i],q[i],0); 81 pf("%d\n",mn); 82 return 0; 83 }