$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 }
代码戳这里

 

posted @ 2019-10-30 17:20  小叽居biubiu  阅读(136)  评论(0编辑  收藏  举报