$NOIP2002$ 题解报告
目录
$Luogu\ P1031$ 均分纸牌$(\ √\ )$
$Luogu\ P1032$ 字串变换$(\ √\ )$
$Luogu\ P1033$ 自由落体$(\ √\ )$
$Luogu\ P1034$ 矩形覆盖$(\ √\ )$
$Luogu\ P1031$ 均分纸牌
先算出平均值,然后处理出每堆纸牌与平均值的关系,多了则为$+$,少了为$-$。然后每次把当前这一堆的牌改变,加到下一堆牌里,这样一定是最优的
1 #include<bits/stdc++.h> 2 using namespace std; 3 int a[102]; 4 int main(){ 5 int n,i,ave=0,step=0; 6 cin>>n; 7 for(i=1;i<=n;i++) 8 { 9 cin>>a[i];ave+=a[i]; 10 } 11 ave/=n; 12 for(i=1;i<=n;i++) a[i]-=ave; 13 i=1; 14 int j=n; 15 while(a[i]==0&&i<n) i++; 16 while(a[j]==0&&j>1) j--; 17 while(i<j) 18 { 19 a[i+1]+=a[i]; 20 a[i]=0; 21 step++;i++; 22 while(a[i]==0&&i<j) i++; 23 } 24 cout<<step<<endl; 25 return 0; 26 }
$Luogu\ P1032$ 字串变换
直接$bfs$,枚举每个转换方式能否匹配,用$map$判重
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 sf scanf 11 #define ull unsigned ll 12 #define mem(a,b) memset(a,b,sizeof(a)) 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=42; 21 string A,B,a[10],b[10]; 22 struct node{string s;int t;}p; 23 queue<node> q; 24 map<string,int> vis; 25 int n=1,lena[10],lenb[10]; 26 string change(const string &x,ri i,ri j){ 27 string as=""; 28 if(j+lena[i]>x.length())return as; 29 go(k,0,lena[i]-1)if(x[j+k]!=a[i][k])return as; 30 as=x.substr(0,j); 31 as+=b[i];as+=x.substr(j+lena[i]); 32 return as; 33 } 34 int main(){ 35 freopen("1.in","r",stdin); 36 freopen("1.out","w",stdout); 37 cin>>A>>B;q.push((node){A,0});vis[A]=1; 38 while(cin>>a[n]>>b[n]){lena[n]=a[n].length();lenb[n]=b[n].length();n++;}n--; 39 while(!q.empty()){ 40 p=q.front();q.pop(); 41 if(p.t>10)break; 42 if(p.s==B){pf("%d\n",p.t);return 0;} 43 ri len=p.s.length(); 44 go(i,1,n)go(j,0,len-1){ 45 string chg=change(p.s,i,j); 46 if(chg!=""){ 47 node nw;nw.s=chg;nw.t=p.t+1; 48 if(!vis.count(nw.s))q.push(nw),vis[nw.s]=1; 49 } 50 } 51 } 52 puts("NO ANSWER!"); 53 return 0; 54 }
$Luogu\ P1033$ 自由落体
算出小车能接到的小球的位置范围,直接统计个数即可
1 #include<bits/stdc++.h> 2 using namespace std; 3 float H,S,V,L,K,n; 4 int ans=0; 5 int main(){ 6 scanf("%f%f%f%f%f%f",&H,&S,&V,&L,&K,&n); 7 float t1,t2,l,r; 8 t1=sqrt((H-K)/5); 9 t2=sqrt(H/5); 10 l=S-V*t2-0.0001; 11 r=S+L-V*t1+0.0001; 12 for(int i=max(0,int(ceil(l)));i<=min(n-1,r);i++) 13 ans++; 14 printf("%d",ans); 15 return 0; 16 }
$Luogu\ P1034$ 矩形覆盖
$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 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=52; 19 int n,k,R,ans=1e9+7,a[N],b[N]; 20 struct node{int x,y;}p[N]; 21 struct square{int x1,y1,x2,y2,s;}q[5],Q[5]; 22 il bool cmp(node a,node b){return a.x==b.x?a.y<b.y:a.x<b.x;} 23 il bool CMP(square a,square b){return a.x1<b.x1;} 24 il bool check(ri num){ 25 go(i,1,num)Q[i]=q[i]; 26 sort(Q+1,Q+1+num,CMP); 27 go(i,1,num-1) 28 if(Q[i+1].x1<=Q[i].x2&&((Q[i+1].y1<=Q[i].y2&&Q[i+1].y1>=Q[i].y1)||(Q[i+1].y2>=Q[i].y1&&Q[i+1].y1<=Q[i].y1)))return 0; 29 return 1; 30 } 31 il void work(ri id,ri num,ri sum){ 32 if(sum>=ans||!check(num))return; 33 //cout<<"id="<<id<<" num="<<num<<" sum="<<sum<<endl; 34 if(id>n){if(num==k)ans=sum;return;} 35 ri x=p[id].x,y=p[id].y; 36 back(i,num,1){ 37 square bf=q[i]; 38 if(y<q[i].y1)q[i].y1=y; 39 if(y>q[i].y2)q[i].y2=y; 40 if(x>q[i].x2)q[i].x2=x; 41 ri add=(q[i].x2-q[i].x1)*(q[i].y2-q[i].y1)-q[i].s; 42 q[i].s=(q[i].x2-q[i].x1)*(q[i].y2-q[i].y1); 43 work(id+1,num,sum+add);q[i]=bf; 44 } 45 if(num<k){ 46 q[num+1]=(square){x,y,x,y,0}; 47 work(id+1,num+1,sum); 48 } 49 return; 50 } 51 int main(){ 52 //freopen("1.in","r",stdin); 53 //freopen("1.out","w",stdout); 54 n=fr();k=fr(); 55 go(i,1,n)p[i]=(node){fr(),fr()}; 56 sort(p+1,p+1+n,cmp);p[0].x=-1; 57 work(1,0,0); 58 pf("%d\n",ans); 59 return 0; 60 }