码迷,mamicode.com
首页 > 其他好文 > 详细

coderforces Gym 100803A/Aizu 1345/CSU 1536/UVALive 6832 Bit String Reordering(未完)

时间:2016-07-07 19:44:02      阅读:207      评论:0      收藏:0      [点我收藏+]

标签:

Portal: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1345

     http://codeforces.com/gym/100803/attachments  A题

好题!

坑不多,切入比较难

一开始的想法是暴力,由于求得是最小解且此图太大无边界,所以不能DFS,首先想到BFS

解法1 BFS+STL queue

技术分享
 1 #include<iostream>
 2 #include<algorithm>
 3 #include<set>
 4 #include<cstdio>
 5 #include<cstdlib>
 6 #include<cmath>
 7 #include<queue>
 8 using namespace std;
 9 #define FOR(i,j,k) for(int i=j;i<=k;i++)
10 #define FORD(i,j,k) for(int i=j;i>=k;i--)
11 #define LL long long
12 #define SZ(x) x.size()
13 int vis[40000];
14 int x,k,n,m,s,ans,start,end1,end2,dight;
15 int bfs()
16 {
17     queue<int> q1,q2;
18     q1.push(start);
19     q2.push(1);
20     vis[start]=1;
21     while(q1.front()!=end1&&q1.front()!=end2)
22     {
23         int fr=q1.front();
24         int fv=q2.front();
25         FOR(i,0,n-2)
26         {
27             if((fr&(1<<i))&&!(fr&(1<<(i+1))))
28             {
29                 ans=fr+(1<<i);
30                 if(!vis[ans]) {vis[ans]=1;q1.push(ans);q2.push(fv+1);}
31             }
32             else if(!(fr&(1<<i))&&(fr&(1<<(i+1))))
33             {
34                 ans=fr-(1<<i);
35                 if(!vis[ans]) {vis[ans]=1;q1.push(ans);q2.push(fv+1);}
36             }
37         }
38         q1.pop();
39         q2.pop();
40     }
41     return q2.front()-1;
42 }
43 int main()
44 {
45 cin>>n>>m;
46 dight=1;
47 FORD(i,n-1,0)
48 {
49     cin>>x;
50     start+=x<<i;
51 }
52 int c=n;
53 FOR(i,1,m)
54 {
55     cin>>x;
56     FOR(j,1,x)
57     {
58         c--;
59         end1+=dight<<c;
60         end2+=(1-dight)<<c;
61     }
62     dight^=1;
63 }
64 cout<<bfs()<<endl;
65 return 0;
66 }
蛋疼的代码

解法2 BFS+手写queue

技术分享
 1 #include<iostream>
 2 #include<algorithm>
 3 #include<set>
 4 #include<cstdio>
 5 #include<cstdlib>
 6 #include<cmath>
 7 //#include<queue>
 8 using namespace std;
 9 #define FOR(i,j,k) for(int i=j;i<=k;i++)
10 #define FORD(i,j,k) for(int i=j;i>=k;i--)
11 #define LL long long
12 #define SZ(x) x.size()
13 int vis[40000];
14 int x,k,n,m,s,ans,start,end1,end2,dight;
15 
16 int bfs()
17 {
18     int q1[40000];int L1=1;int R1=0;    
19     int q2[40000];int L2=1;int R2=0;
20     q1[++R1]=start;
21     q2[++R2]=1;
22     vis[start]=1;
23     while(q1[L1]!=end1&&q1[L1]!=end2)
24     {
25         int fr=q1[L1];
26         int fv=q2[L2];
27         FOR(i,0,n-2)
28         {
29             if((fr&(1<<i))&&!(fr&(1<<(i+1))))
30             {
31                 ans=fr+(1<<i);
32                 if(!vis[ans]) {vis[ans]=1;q1[++R1]=ans;q2[++R2]=fv+1;}
33             }
34             else if(!(fr&(1<<i))&&(fr&(1<<(i+1))))
35             {
36                 ans=fr-(1<<i);
37                 if(!vis[ans]) {vis[ans]=1;q1[++R1]=ans;q2[++R2]=fv+1;}
38             }
39         }
40         L1++;
41         L2++;
42     }
43     return q2[L2]-1;
44 }
45 int main()
46 {
47 cin>>n>>m;
48 dight=1;
49 FORD(i,n-1,0)
50 {
51     cin>>x;
52     start+=x<<i;
53 }
54 int c=n;
55 FOR(i,1,m)
56 {
57     cin>>x;
58     FOR(j,1,x)
59     {
60         c--;
61         end1+=dight<<c;
62         end2+=(1-dight)<<c;
63     }
64     dight^=1;
65 }
66 cout<<bfs()<<endl;
67 return 0;
68 }
同样的代码

比较同样情况下STL的queue和手写的queue,我发现STL的queue内存比手写的多了4KB

这是个严重的问题,因为STL经常pop元素,是动态的,它的内存一定较小,但即便在手写的queue固定大小为8e5个int的情况下,仍然多4KB,即1e3个int

STL的queue在此题理论上能够最多有16384个元素,所以事实上同等长度的queue所用内存相当于3到4倍同等int

所以,我们应该谨慎使用STL,为保险起见,用queue时数据输入的极限容量不得多于1e7,即1/10int在32768KB下容量左右

 

在解法1/2的代码中使用了位运算的黑科技

技术分享
FORD(i,n-1,0)
{
    cin>>x;
    start+=x<<i;
}
int c=n;
FOR(i,1,m)
{
    cin>>x;
    FOR(j,1,x)
    {
        c--;
        end1+=dight<<c;
        end2+=(1-dight)<<c;
    }
    dight^=1;
}


///


    if((fr&(1<<i))&&!(fr&(1<<(i+1))))
            {
                ans=fr+(1<<i);
                if(!vis[ans]) {vis[ans]=1;q1[++R1]=ans;q2[++R2]=fv+1;}
            }
            else if(!(fr&(1<<i))&&(fr&(1<<(i+1))))
            {
                ans=fr-(1<<i);
                if(!vis[ans]) {vis[ans]=1;q1[++R1]=ans;q2[++R2]=fv+1;}
            }
神奇的做法

其中(fr&(1<<i))&&!(fr&(1<<(i+1)))最妙

fr&(1<<i)表示判断fr的二进制表示中第i位是否为1(利用了c++非0为真的机制)

这样使用黑科技的原因是这题中交换相同的二进制位是没有意义

所以仅仅交换01和10来产生当前数字的邻居

 

解法3(2) 贪心

 

coderforces Gym 100803A/Aizu 1345/CSU 1536/UVALive 6832 Bit String Reordering(未完)

标签:

原文地址:http://www.cnblogs.com/mukoiaoi/p/5651018.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!