1. 程式人生 > >夜深人靜寫題解--杭電第五場

夜深人靜寫題解--杭電第五場

1001 fraction

  題意:求出最小的B使得A==BX(MOD P) 0<A<B。

  思路: 

 

程式碼:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 void f(ll lup,ll ldown,ll rup,ll rdown,ll &x,ll &y)
 5 {
 6     ll mm=lup/ldown+1;
 7     if(mm<=rup/rdown)
 8     {
 9         x=mm;
10         y=1;
11         return ;
12     }
13     mm--;
14     lup-=mm*ldown;
15     rup-=mm*rdown;
16     f(rdown,rup,ldown,lup,y,x);
17     x+=(mm)*y;
18     return ;
19 }
20 int main()
21 {
22     int t;
23     scanf("%d",&t);
24     while(t--)
25     {
26         ll p,x,a,b;
27         scanf("%lld%lld",&p,&x);
28         f(p,x,p,x-1,a,b);
29         ll z=x*a-b*p;
30         //printf("%lld %lld\n",a,b);
31         printf("%lld/%lld\n",z,a);
32     }
33 
34 }
View Code

1002 three arrays

  題意:對於兩個陣列A和B,任意安排A中的順序,任意安排B中的順序,陣列C為Ai ^ Bi 的值,求出使得C字典序最小的情況,輸出C陣列。

  思路:由於異或的性質,我們就儘可能的將數完備的“匹配“,貪心的對高位匹配,兩個數字相異或,高位如果儘可能的消去,得到的結果就會越小,所以貪心的求解,由於資料範圍的侷限性,我們需要對陣列A和B分別建立一個01字典樹,每次貪心的在字典樹上進行匹配,然後將其儲存,考慮到我們求解過程中並不一定按照順序求解,所以為保證字典序最小,需要將C陣列進行排序後輸出。

 程式碼:

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int maxn=1e5+7;
  4 struct node
  5 {
  6     int s[2];
  7     bool en;
  8     int si;
  9 };
 10 int ans[maxn];
 11 struct trie
 12 {
 13     node a[31*maxn];
 14     int num;
 15     void init(int n)
 16     {
 17         memset(a,0,sizeof(node)*(n*31+1));
 18         num=1;
 19     }
 20     void inser(int x)
 21     {
 22         int st=1;
 23         for(int i=30;i>=0;i--)
 24         {
 25             ++a[st].si;
 26             int q=(x>>i)&1;
 27             if(a[st].s[q]==0)
 28             {
 29                 a[st].s[q]=++num;
 30                 st=num;
 31             }
 32             else
 33             {
 34                 st=a[st].s[q];
 35             }
 36         }
 37         ++a[st].si;
 38         a[st].en=1;
 39     }
 40 
 41 }trie1,trie2;
 42 
 43 int main()
 44 {
 45     int t;
 46     scanf("%d",&t);
 47     while(t--)
 48     {
 49         int n;
 50         scanf("%d",&n);
 51         trie1.init(n);trie2.init(n);
 52         for(int i=1;i<=n;i++)
 53         {
 54             int x;
 55             scanf("%d",&x);
 56             trie1.inser(x);
 57         }
 58         for(int i=1;i<=n;i++)
 59         {
 60             int x;
 61             scanf("%d",&x);
 62             trie2.inser(x);
 63         }
 64         for(int i=1;i<=n;i++)
 65         {
 66             int ans1=0;
 67             int l1=1;
 68             int l2=1;
 69             while(!trie1.a[l1].en&&!trie2.a[l2].en)
 70             {
 71                 --trie1.a[l1].si;--trie2.a[l2].si;
 72                 ans1<<=1;
 73                 int t10=trie1.a[trie1.a[l1].s[0]].si>0;
 74                 int t11=trie1.a[trie1.a[l1].s[1]].si>0;
 75                 int t20=trie2.a[trie2.a[l2].s[0]].si>0;
 76                 int t21=trie2.a[trie2.a[l2].s[1]].si>0;
 77                 if(t11&&t21)
 78                 {
 79                     l1=trie1.a[l1].s[1];
 80                     l2=trie2.a[l2].s[1];
 81                 }
 82                 else if(t10&&t20)
 83                 {
 84                     l1=trie1.a[l1].s[0];
 85                     l2=trie2.a[l2].s[0];
 86                 }
 87                 else if(t11&&t20)
 88                 {
 89                     l1=trie1.a[l1].s[1];
 90                     l2=trie2.a[l2].s[0];
 91                     ans1++;
 92                 }
 93                 else if(t10&&t21)
 94                 {
 95                     l1=trie1.a[l1].s[0];
 96                     l2=trie2.a[l2].s[1];
 97                     ans1++;
 98                 }
 99             }
100             --trie1.a[l1].si;
101             --trie2.a[l2].si;
102             ans[i]=ans1;
103         }
104         sort(ans+1,ans+1+n);
105         for(int i=1;i<=n;i++)
106         {
107             printf("%d",ans[i]);
108             if(i!=n)
109             {
110                 printf(" ");
111             }
112         }
113         printf("\n");
114     }
115 }
View Code

1004 equation

  題意:求解滿足∑|ai⋅x+bi|=C的所有x值,沒有則輸出-1

  思路:考慮到一次函式y=ax+b具有可加性,y=|ai⋅x+bi|是將其位於x軸下面的影象翻轉到上方,所以我們對於每個翻轉點進行列舉,列舉在每個區間內函式的疊加情況,由於其處理具有後效性,所以我們可以對其在翻轉點排序之後進行字首和的處理,可以O(1)的算出貢獻情況,對當前一次函式y=kx+b與y=c進行交點求解,判斷座標是否滿足要求,滿足加入答案。

程式碼:

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int maxn=1e5+7;
  4 const double eps=1e-8;
  5 struct node
  6 {
  7     int a;
  8     int b;
  9 } bos[maxn],ans[maxn];
 10 bool cmp(node x,node y)
 11 {
 12     return (-1.0*x.b/x.a)<(-1.0*y.b/y.a);
 13 }
 14 bool cmp2(node x,node y)
 15 {
 16     return x.b/x.a<y.b/y.a;
 17 }
 18 long long int sum[maxn],sum1[maxn];
 19 int main()
 20 {
 21     int t;
 22     scanf("%d",&t);
 23     while(t--)
 24     {
 25         int n,c;
 26         scanf("%d%d",&n,&c);
 27         for(int i=1; i<=n; i++)
 28         {
 29             scanf("%d%d",&bos[i].a,&bos[i].b);
 30         }
 31         sort(bos+1,bos+n+1,cmp);
 32         sum[0]=0;
 33         for(int i=1; i<=n; i++)
 34         {
 35             sum[i]=sum[i-1]-bos[i].a;
 36             sum1[i]=sum1[i-1]-bos[i].b;
 37         }
 38         int fi=0;
 39         long long int to=sum1[n]-c;
 40         to=-to;
 41         long long int bi=sum[n];
 42         int temp=0;
 43         if(bi==0)
 44         {
 45             if(to==0)
 46             {
 47                 fi=1;
 48             }
 49         }
 50         else
 51         {
 52             if((1.0*to)/bi<=(-1.0*bos[1].b)/bos[1].a||abs((1.0*to)/bi-(-1.0*bos[1].b)/bos[1].a)<=eps)
 53             {
 54                 ans[temp].b=to;
 55                 ans[temp].a=bi;
 56                 temp++;
 57             }
 58         }
 59         long long int hi=0;
 60         long long int low=0;
 61         for(int i=1; i<=n-1; i++)
 62         {
 63             hi+=bos[i].b;
 64             low+=bos[i].a;
 65             to=sum1[n]-(sum1[i])+hi-c;
 66             to=-to;
 67             bi=sum[n]-(sum[i])+low;
 68             //printf("to=%lld bi=%lld\n",sum1[n]-(sum1[i]),bi);
 69             if(bi==0)
 70             {
 71                 if(to==0)
 72                 {
 73                     fi=1;
 74                 }
 75             }
 76             else
 77             {
 78                 if(((((1.0*to)/bi)>=((-1.0*bos[i].b)/bos[i].a))||abs(((1.0*to)/bi)-((-1.0*bos[i].b)/bos[i].a))<=eps)&&(((1.0*to)/bi<=((-1.0*bos[i+1].b)/bos[i+1].a))||
 79                    abs((1.0*to)/bi-((-1.0*bos[i+1].b)/bos[i+1].a))<=eps))
 80                 {
 81                     //printf(" ?? %d %d\n",bos[i].b,bos[i].a);
 82                     ans[temp].b=to;
 83                     ans[temp].a=bi;
 84                     temp++;
 85                 }
 86             }
 87         }
 88         hi+=bos[n].b;
 89         low+=bos[n].a;
 90         to=hi-c;
 91         to=-to;
 92         bi=low;
 93         //printf("to=%lld bi=%lld\n",to,bi);
 94         if(bi==0)
 95         {
 96             if(to==0)
 97             {
 98                 fi=1;
 99             }
100         }
101         else
102         {
103             if((1.0*to)/bi>=(-1.0*bos[n].b)/bos[n].a||abs((1.0*to)/bi-(-1.0*bos[n].b)/bos[n].a)<=eps)
104             {
105                 ans[temp].b=to;
106                 ans[temp].a=bi;
107                 temp++;
108             }
109         }
110         if(fi==1)
111         {
112             printf("-1\n");
113         }
114         else
115         {
116             //printf("%d",temp);
117             sort(ans,ans+temp,cmp2);
118             int jishu=0;
119             for(int i=0; i<temp; i++)
120             {
121                 int gcd=__gcd(abs(ans[i].a),abs(ans[i].b));
122                 //printf("%d ++ \n",gcd);
123                 ans[i].a/=gcd;
124                 ans[i].b/=gcd;
125                 if(ans[i].a<0)
126                 {
127                     ans[i].a=-ans[i].a;
128                     ans[i].b=-ans[i].b;
129                 }
130                 if(i-1>=0&&ans[i].a==ans[i-1].a&&ans[i].b==ans[i-1].b)
131                 {
132 
133                 }
134                 else jishu++;
135                // printf(" %d/%d",ans[i].b,ans[i].a);
136             }
137             printf("%d",jishu);
138             for(int i=0; i<temp; i++)
139             {
140                 int gcd=__gcd(abs(ans[i].a),abs(ans[i].b));
141                 //printf("%d ++ \n",gcd);
142                 ans[i].a/=gcd;
143                 ans[i].b/=gcd;
144                 if(ans[i].a<0)
145                 {
146                     ans[i].a=-ans[i].a;
147                     ans[i].b=-ans[i].b;
148                 }
149                 if(ans[i].a==ans[i-1].a&&ans[i].b==ans[i-1].b)
150                 {
151 
152                 }
153                 else
154                 printf(" %d/%d",ans[i].b,ans[i].a);
155             }
156             printf("\n");
157         }
158     }
159 }
View Code

1005  permutation 1

  題意:給出陣列A,陣列B為A中連續性兩項的差值,Bi=Ai-A(i-1),求出B第k個字典序大的序列,陣列長度小於20,k<10000

  思路:考慮到K的範圍,當N<=8時直接進行全排列求解,當N>8時,分開進行討論,考慮到8!為40320,則可以知道N的前幾位是固定的,對於後面的跑個全排列就行。

程式碼:

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int maxn=1e5+7;
  4 int b[40];
  5 int ans[50005][40];
  6 int ans1[50005][40];
  7 struct node
  8 {
  9     string x;
 10     int pos;
 11 } a[50005],q[50005];
 12 bool cmp(node a,node b)
 13 {
 14     return a.x<b.x;
 15 }
 16 int main()
 17 {
 18     int t;
 19     for(int i=1; i<=8; i++)
 20     {
 21         b[i]=i;
 22     }
 23     b[0]=0;
 24     int temp=0;
 25     do
 26     {
 27         q[temp].x="";
 28         for(int i=1; i<=8; i++)
 29         {
 30             ans1[temp][i]=b[i];
 31         }
 32         for(int i=1; i<=8; i++)
 33         {
 34             q[temp].x+=char(b[i]-b[i-1]+'0');
 35             q[temp].x+='|';
 36         }
 37         q[temp].pos=temp;
 38         temp++;
 39     }
 40     while(next_permutation(b+1,b+8+1));
 41     sort(q,q+temp,cmp);
 42     scanf("%d",&t);
 43     while(t--)
 44     {
 45         int n,k;
 46         scanf("%d%d",&n,&k);
 47         for(int i=1; i<=n; i++)
 48         {
 49             b[i]=i;
 50         }
 51         if(n<9)
 52         {
 53             temp=0;
 54             do
 55             {
 56                 a[temp].x="";
 57                 for(int i=1; i<=n; i++)
 58                 {
 59                     ans[temp][i]=b[i];
 60                 }
 61                 for(int i=2; i<=n; i++)
 62                 {
 63                     a[temp].x+=char(b[i]-b[i-1]+'0');
 64                     a[temp].x+='|';
 65                 }
 66                 a[temp].pos=temp;
 67                 temp++;
 68             }
 69             while(next_permutation(b+1,b+n+1));
 70             sort(a,a+temp,cmp);
 71             for(int j=1; j<=n; j++)
 72             {
 73                 printf("%d",ans[a[k-1].pos][j]);
 74                 if(j!=n)
 75                 {
 76                     printf(" ");
 77                 }
 78             }
 79             printf("\n");
 80         }
 81         else if(n==9)
 82         {
 83             if(k<=5040)
 84             {
 85                 b[1]=2;
 86                 b[2]=3;
 87                 b[3]=4;
 88                 b[4]=5;
 89                 b[5]=6;
 90                 b[6]=7;
 91                 b[7]=8;
 92                 b[0]=1;
 93                 temp=0;
 94                 do
 95                 {
 96                     a[temp].x="";
 97                     for(int i=1; i<=7; i++)
 98                     {
 99                         ans[temp][i]=b[i];
100                     }
101                     for(int i=1; i<=7; i++)
102                     {
103                         a[temp].x+=char(b[i]-b[i-1]+'0');
104                         a[temp].x+='|';
105                     }
106                     a[temp].pos=temp;
107                     temp++;
108                 }
109                 while(next_permutation(b+1,b+7+1));
110                 sort(a,a+temp,cmp);
111                 printf("9 1 ");
112                 for(int j=1; j<=7; j++)
113                 {
114                     printf("%d",ans[a[k-1].pos][j]);
115                     if(j!=7)
116                     {
117                         printf(" ");
118                     }
119                 }
120                 printf("\n");
121             }
122             else
123             {
124                 b[1]=2;
125                 b[2]=3;
126                 b[3]=4;
127                 b[4]=5;
128                 b[5]=6;
129                 b[6]=7;
130                 b[7]=9;
131                 b[0]=1;
132                 temp=0;
133                 do
134                 {
135                     a[temp].x="";
136                     for(int i=1; i<=7; i++)
137                     {
138                         ans[temp][i]=b[i];
139                     }
140                     for(int i=1; i<=7; i++)
141                     {
142                         a[temp].x+=char(b[i]-b[i-1]+'0');
143                         a[temp].x+='|';
144                     }
145                     a[temp].pos=temp;
146                     temp++;
147                 }
148                 while(next_permutation(b+1,b+7+1));
149                 int ff=temp;
150                 b[1]=1;
151                 b[2]=3;
152                 b[3]=4;
153                 b[4]=5;
154                 b[5]=6;
155                 b[6]=7;
156                 b[7]=8;
157                 b[0]=2;
158                 do
159                 {
160                     a[temp].x="";
161                     for(int i=1; i<=7; i++)
162                     {
163                         ans[temp][i]=b[i];
164                     }
165                     for(int i=1; i<=7; i++)
166                     {
167                         a[temp].x+=char(b[i]-b[i-1]+'0');
168                         a[temp].x+='|';
169                     }
170                     a[temp].pos=temp;
171                     temp++;
172                 }
173                 while(next_permutation(b+1,b+7+1));
174                 sort(a,a+temp,cmp);
175                 if(a[k-1].pos<ff)
176                 {
177                     printf("8 1 ");
178                 }
179                 else
180                 {
181                     printf("9 2 ");
182                 }
183                 for(int j=1; j<=7; j++)
184                 {
185                     printf("%d",ans[a[k-1-5040].pos][j]);
186                     if(j!=7)
187                     {
188                         printf(" ");
189                     }
190                 }
191                 printf("\n");
192             }
193         }
194         else
195         {
196             printf("%d",n);
197             for(int i=1; i<=n-9; i++)
198             {
199                 printf(" %d",i);
200             }
201             for(int j=1; j<=8; j++)
202             {
203                 printf(" %d",ans1[q[k-1].pos][j]+n-9);
204             }
205             printf("\n");
206         }
207     }
208 }
View Code

1006 string matching

  思路:擴充套件kmp裸題

程式碼:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e6+7;
 4 char a[maxn];
 5 int nex[maxn];
 6 int jishu[maxn];
 7 void pre_kmp(char x[],int m)
 8 {
 9     nex[0]=m;
10     int j=0;
11     while(j+1<m&&x[j]==x[j+1])j++;
12     nex[1]=j;
13     int k=1;
14     for(int i=2; i<m; i++)
15     {
16         int p=nex[k]+k-1;
17         int l=nex[i-k];
18         if(i+l<p+1)nex[i]=l;
19         else
20         {
21             j=max(0,p-i+1);
22             while(i+j<m&&x[i+j]==x[j])j++;
23             nex[i]=j;
24             k=i;
25         }
26     }
27 }
28 int main()
29 {
30     int t;
31     scanf("%d",&t);
32     while(t--)
33     {
34         scanf("%s",a);
35         int len=strlen(a);
36         pre_kmp(a,len);
37         long long int ans=0;
38         for(int i=1; i<len; i++)
39         {
40             ans+=nex[i];
41             if(nex[i]!=len-i)
42             {
43                 ans++;
44             }
45         }
46         printf("%lld\n",ans);
47     }
48 }
View Code

1007  permutation 2

  題意:你有三個正整數 n,x ,y。請計算一下排列的數量1 ~ N 滿足以下條件:
         1.p1= x
         2.pn= y
         3.abs(pi-p(i-1))<=2

  思路:打表找規律

程式碼:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const long long int mod=998244353;
 4 const int maxn=1e5+7;
 5 long long int a[maxn];
 6 long long int ans[maxn];
 7 int main()
 8 {
 9     int t;
10     scanf("%d",&t);
11     a[1]=1,a[2]=1,a[3]=1;
12     for(int i=4;i<=maxn;i++)
13         a[i]=(a[i-1]+a[i-3])%mod;
14     while(t--)
15     {
16         int n,x,y;
17         scanf("%d%d%d",&n,&x,&y);
18         if(x==1&&y==n)
19         {
20             printf("%lld\n",a[y]);
21         }
22         else if(x!=1&&y!=n)
23         {
24             printf("%lld\n",a[y-x-1]);
25         }
26         else printf("%lld\n",a[y-x]);
27     }
28 }
View Code

&n