团体程序设计天梯赛(CCCC) L3015 球队“食物链” 状态压缩

团体程序设计天梯赛代码。体现代码技巧,比赛技巧。  https://github.com/congmingyige/cccc_code

  1 #include <cstdio>
  2 #include <cstdlib>
  3 #include <cmath>
  4 #include <cstring>
  5 #include <string>
  6 #include <algorithm>
  7 #include <set>
  8 #include <map>
  9 #include <queue>
 10 #include <iostream>
 11 using namespace std;
 12 
 13 #define ll long long
 14 
 15 /*
 16 1肯定是要放在第一位
 17 
 18 节省空间
 19 
 20 所有数字前移一位(k作为k-1,0作为n)。
 21 2^20 -> 2^19
 22 
 23 如果
 24 使用康拓展开 19!< max long long
 25 而不是20进制,使用两个变量
 26 
 27 2^19*19*8 /1024/1024 =76
 28 */
 29 
 30 const int maxn=19;
 31 const int inf=1e9;
 32 const double eps=1e-8;
 33 
 34 ll value[maxn],num[1<<maxn][maxn];
 35 bool f[1<<maxn][maxn],vis[maxn],r[maxn+1][maxn+1];
 36 int ii,a[maxn],v=0,n,pr[maxn],g_pr=0;
 37 
 38 void dfs(int k,int d)
 39 {
 40     int i;
 41     if (k==0)
 42     {
 43         int j,l,gl;
 44         ll num1;
 45         for (i=1;i<=ii;i++)
 46             if (f[v][a[i]])
 47                 for (j=0;j<=n-2;j++)
 48                     if (!vis[j] && r[a[i]][j])
 49                     {
 50                         gl=0;
 51                         for (l=0;l<j;l++)
 52                             if (vis[l])
 53                                 gl++;
 54                         num1=num[v][a[i]]+value[18-ii]*(j-gl);
 55                         if (!f[v|1<<j][j] || num1<num[v|1<<j][j])
 56                         {
 57                             f[v|1<<j][j]=1;
 58                             num[v|1<<j][j]=num1;
 59                         }
 60                     }
 61         return;
 62     }
 63     for (i=d;i<=n-2;i++)
 64     {
 65         v+=1<<i;
 66         a[k]=i;
 67         vis[i]=1;
 68         dfs(k-1,i+1);
 69         vis[i]=0;
 70         v-=1<<i;
 71     }
 72 }
 73 
 74 void work()
 75 {
 76     int i;
 77     if (n==2)
 78     {
 79         if (r[0][1] && r[1][0])
 80             printf("1 2");
 81         else
 82             printf("No Solution");
 83         exit(0);
 84     }
 85     for (i=0;i<=n-2;i++)
 86         if (r[n-1][i])
 87             f[1<<i][i]=1,num[1<<i][i]=value[18]*i;
 88     for (ii=1;ii<=n-2;ii++)
 89         dfs(ii,0);
 90 }
 91 
 92 int main()
 93 {
 94     int i,j,k,ind,x,y;
 95     ll v;
 96     char c;
 97     value[0]=1;
 98     for (i=1;i<=18;i++)
 99         value[i]=value[i-1]*i;
100 
101     scanf("%d",&n);
102     for (i=0;i<n;i++)   ///start from 0 (2^0 = 1)
103     {
104         x=(i==0)?n-1:i-1;
105         scanf("%c",&c);
106         for (j=0;j<n;j++)
107         {
108             y=(j==0)?n-1:j-1;
109             scanf("%c",&c);
110             if (c=='W')
111                 r[x][y]=1;
112             else if (c=='L')
113                 r[y][x]=1;
114         }
115     }
116     work();
117 
118     j=(1<<(n-1))-1;
119     num[j][n-1]=9e18;
120     ind=n-1;
121 
122     for (i=0;i<=n-2;i++)
123         if (f[j][i] && r[i][n-1] && num[j][i]<num[j][ind])
124             ind=i;
125 
126     if (ind==n-1)
127     {
128         printf("No Solution");
129         return 0;
130     }
131 
132     memset(vis,0,sizeof(vis));
133     v=num[j][ind];
134     printf("%d",1);
135     for (i=18;i>=20-n;i--)
136     {
137         j=v/value[i];
138         k=0;
139         while (vis[k])
140             k++;
141         while (j--)
142         {
143             k++;
144             while (vis[k])
145                 k++;
146         }
147         printf(" %d",k+2);
148         vis[k]=1;
149         v%=value[i];
150     }
151 
152     return 0;
153 }
154 /*
155 20
156 -WWWWWWWWWWWWWWWWWWW
157 W-WWWWWWWWWWWWWWWWWW
158 WW-WWWWWWWWWWWWWWWWW
159 WWW-WWWWWWWWWWWWWWWW
160 WWWW-WWWWWWWWWWWWWWW
161 WWWWW-WWWWWWWWWWWWWW
162 WWWWWW-WWWWWWWWWWWWW
163 WWWWWWW-WWWWWWWWWWWW
164 WWWWWWWW-WWWWWWWWWWW
165 WWWWWWWWW-WWWWWWWWWW
166 WWWWWWWWWW-WWWWWWWWW
167 WWWWWWWWWWW-WWWWWWWW
168 WWWWWWWWWWWW-WWWWWWW
169 WWWWWWWWWWWWW-WWWWWW
170 WWWWWWWWWWWWWW-WWWWW
171 WWWWWWWWWWWWWWW-WWWW
172 WWWWWWWWWWWWWWWW-WWW
173 WWWWWWWWWWWWWWWWW-WW
174 WWWWWWWWWWWWWWWWWW-W
175 WWWWWWWWWWWWWWWWWWW-
176 
177 3
178 -WW
179 W-W
180 WW-
181 
182 3
183 -WD
184 D-W
185 WD-
186 */

猜你喜欢

转载自www.cnblogs.com/cmyg/p/10720457.html