$NOIP1998$ 题解报告

目录

•$Luogu\ P1011$ 车站$(\ √\ )$

•$Luogu\ P1012$ 拼数$(\ √\ )$

•$Luogo\ P1013$ 进制位$(\ √\ )$


 

$Luogu\ P1011$ 车站

题目传送门

这题看起来就很斐波那契

我们直接推式子即可,设第二站上车下车的人数均为$b$,设$f[i]$为到达第$i$站时的人数,$up[i]$为第$i$站上车的人数,$down[i]$为第$i$站下车的人数

$f[1]=0,up[1]=a,down[1]=0$

$f[2]=a,up[2]=b,down[2]=b$

$f[3]=a,up[3]=a+b,down[3]=b$

$f[4]=2*a+b,up[4]=a+2*b,down[4]=a+b$

$f[5]=3*a+3*b,up[5]=2*a+3*b,down[5]=a+2*b$

$\cdots\cdots$

我们把$a,b$的系数单独提出来就可以发现规律

$(0,0),(1,0),(0,0)$

$(1,0),(0,1),(0,1)$

$(1,0),(1,1),(0,1)$

$(2,1),(1,2),(1,1)$

$(3,3),(2,3),(1,2)$

$\cdots\cdots$

按照题目模拟,将系数相加即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 struct UDN{
 4     int k1,k2;//k1,k2代表系数
 5 }up[22],now[22];
 6 int a,n,m,x;
 7 int main(){
 8     scanf("%d%d%d%d",&a,&n,&m,&x);
 9     now[1].k1=up[1].k1=1,now[1].k2=up[1].k2=0;
10     up[2].k2=now[2].k1=1,up[2].k1=now[2].k2=0;
11     for(int i=3;i<n;i++){
12         up[i].k1=up[i-1].k1+up[i-2].k1;
13         up[i].k2=up[i-1].k2+up[i-2].k2;
14         now[i].k1=now[i-1].k1+up[i-2].k1;
15         now[i].k2=now[i-1].k2+up[i-2].k2;
16     }
17     int down=(m-now[n-1].k1*a)/now[n-1].k2;
18     int ans=now[x].k1*a+now[x].k2*down;
19     cout<<ans;
20 }
代码戳这里

 


 

$Luogu\ P1012$ 拼数

题目传送门

直接贪心排序

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 string a[25];
 4 int n;
 5 bool px(string x,string y){
 6     return x+y>y+x;
 7 }
 8 int main(){
 9     scanf("%d",&n);
10     for(int i=1;i<=n;i++)
11       cin>>a[i];
12     sort(a+1,a+n+1,px);
13     for(int i=1;i<=n;i++)
14       cout<<a[i];
15     return 0;
16 }
代码戳这里

 


 

$Luogu\ P1013$ 进制位

题目传送门

易知输入为$n$,则必定是$n-1$进制的运算,枚举$0~n-2$的数字,判断是否合法即可(我永远喜欢搜索)

 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 int n,num[10],id[30];
19 char c[10][10][2];
20 bool ans=0,vis[10];
21 il bool check(){
22     go(i,1,n-1)go(j,1,n-1){
23         ri sum=num[i]+num[j];
24         ri len=strlen(c[i+1][j+1]);
25         if(len>1){
26             if(sum<n-1)return 0;
27             ri id1=id[c[i+1][j+1][0]-'A'],id2=id[c[i+1][j+1][1]-'A'];
28             if(num[id1]!=sum/(n-1)||num[id2]!=sum%(n-1))return 0;
29         }
30         else{
31             if(sum>=n-1)return 0;
32             ri id1=id[c[i+1][j+1][0]-'A'];
33             if(num[id1]!=sum)return 0;
34         }
35     }
36     return 1;
37 }
38 il void work(ri x,ri sum){
39     if(x==n-1&&check()){ans=1;return;}
40     go(i,0,n-2){
41         if(vis[i])continue;
42         if(ans)return;
43         vis[i]=1;num[x+1]=i;
44         work(x+1,i);
45         vis[i]=0;
46     }
47     return;
48 }
49 int main(){
50     //freopen(".in","r",stdin);
51     //freopen(".out","w",stdout);
52     n=fr();
53     ri count=0;char ch=g();
54     while(count<n*n){
55         while((ch<'A'||ch>'Z')&&ch!='+')ch=g();
56         count++;ri x=count/n+1,y=count%n;
57         if(y==0)x--,y=n;ri s=-1;
58         while((ch>='A'&&ch<='Z')||ch=='+')c[x][y][++s]=ch,ch=g();
59     }
60     go(i,2,n)id[c[1][i][0]-'A']=i-1;
61     go(i,0,n-2){
62         if(ans)break;
63         vis[i]=1,num[1]=i,work(1,i),vis[i]=0;
64     }
65     if(!ans)puts("ERROR!");
66     else{go(i,2,n)pf("%c=%d ",c[1][i][0],num[i-1]);puts("");pf("%d\n",n-1);}
67     return 0;
68 }
代码戳这里

 

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