2013成都网赛 G(x) (HDU 4733)

G(x)

  思路:

  首先搞清楚每个位置上的值有什么意义, 如果第i位的值为1则 第i位与第i+1位不同,反之相同.

  然后考虑s1和s2为什么会不一样, 这是由于x+1后比特位进位导致的,于是得出一个性质:

    如果进位最高在第i位, 则

     x的[0,i-1]位为1;

    x+1的[0,i-1]位为0;

    x/x+1 在[i+1,n]位置的值相同

  同时可以确定G(x)大部分位置的情况.

  最后大概是这样:

           bn  bn-1  ...  bi+1  bi  bi-1  bi-2  ...  b1  

  x                      1    0    0   ...  0 

  x+1                      0    1    1  ...  1

  G(x)                    k    1    0

  G(x+1)                   1-k   1    0  ...  0

  所以做法就是枚举最后的进位,然后根据 *的"??"来统计了.

  细节比较多:

  1. i前面的s1,s2要能够保证相同;

  2. G()中[i,n]区间 1 的个数要保证能使得 x 的第i位为1 和 (x+1) 的第i位为0 , 讨论奇偶性,并利用*的'?';

  3. k=1的情况 不能在第n位出现, 这是为了保证 x<x+1.

 #include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <iostream>
#include <string>
#include <ctime>
#include <algorithm>
#include <cmath>
#include <ctime>
using namespace std;
#define maxn 100010
typedef long long llong;
const llong mod = ;
char g1[maxn],g2[maxn];
int ww[maxn],w1[maxn],ueql[maxn],all1[maxn];
llong f[][maxn];
void pretreat()
{
int i,len;
len = strlen(g1);
memset(ww,,sizeof(ww));
memset(w1,,sizeof(w1));
memset(ueql,,sizeof(ueql));
memset(all1,,sizeof(all1)); for ( i= ; i<len ; i++ )
{
if (g1[i]=='?'&&g2[i]=='?') ww[i]=;
else if (g1[i]==''&&g2[i]=='') all1[i]=;
else if ((g1[i]=='?'&&g2[i]=='') || (g1[i]==''&&g2[i]=='?')) w1[i]=;
else if ((g1[i]==''&&g2[i]=='') || (g1[i]==''&&g2[i]=='')) ueql[i]=;
} for ( i= ; i<len ; i++ )
{
ww[i] += ww[i-];
w1[i] += w1[i-];
all1[i] += all1[i-];
ueql[i] += ueql[i-];
}
} bool can(int pos,int len)
{
int cnt1;
if (g1[pos]==''&&g2[pos]=='') return false;
if (g1[pos]==''&&g2[pos]=='') return false;
if (pos+<len&&(g1[pos+]=='' || g2[pos+]=='')) return false;
if (pos->=&&ueql[pos-]) return false;
if (pos+<len) cnt1 = w1[len-]-w1[pos+]+all1[len-]-all1[pos+]+ueql[len-]-ueql[pos+];
else cnt1 = ;
if (cnt1) return false;
if (pos==len-) return true;
return true;
} void PrintAns(int pos,int k)
{
int i,len,cnt1;
g1[pos]=k+'';
g2[pos]=-k+'';
len = strlen(g1);
if (pos) cnt1 = w1[pos-]+all1[pos-];
else cnt1 = ;
for ( i=len- ; i>pos+ ; i-- ) g1[i]=g2[i]='';
if (pos+<=len-) g1[pos+]=g2[pos+]='';
for ( i= ; i<pos ; i++ )
{
if (g1[i]=='?'&&g2[i]=='') g1[i]='';
if (g1[i]==''&&g2[i]=='?') g2[i]='';
if (g1[i]==''&&g2[i]=='?') g2[i]='';
if (g1[i]=='?'&&g2[i]=='') g1[i]='';
if (g1[i]=='?'&&g2[i]=='?')
{
if (k==)
{
if (cnt1%) g1[i]=g2[i]='';
else g1[i]=g2[i]='';
}else
{
if (cnt1%) g1[i]=g2[i]='';
else g1[i]=g2[i]='';
}
}
}
g1[len]=g2[len]=;
// printf("%s\n%s\n",g1,g2);
cout<<g1<<endl<<g2<<endl;;
} int getvar(int i,int j)
{
if (i== && j>=) return ;
if (i== && j>=) return ;
return f[i][j];
} void solv()
{
int i,flg,pos,len,k,cnt1,cntw;
llong ans=;
len = strlen(g1);
flg = ;
// printf("len=%d\n",len);
// printf("%s\n%s\n",g1,g2);
for ( i= ; i<len ; i++ )
if (can(i,len))
{
// printf("w1[len-1]-w1[pos+1]=%d-%d=%d\n",w1[len-1],w1[i+1],w1[len-1]-w1[i+1]);
if (i) cnt1 = w1[i-] + all1[i-];
else cnt1=;
if (i) cntw = ww[i-];
else cntw=;
// printf("%c %c\n",g1[i],g2[i]);
// printf("i=%d cnt1=%d cntw=%d uneql=%d\n",i,cnt1,cntw,i>0?ueql[i-1]:0);
if (g1[i]!=''&&g2[i]!=''&&i) // k=1
{
if (cnt1%)
{
ans += f[][cntw];
int tmp = getvar(,cntw);
flg += tmp;
if (tmp&&flg==) pos=i,k=;
}else
{
ans += f[][cntw];
int tmp = getvar(,cntw);
flg += tmp;
if (tmp&&flg==) pos=i,k=;
}
}
if (g1[i]!=''&&g2[i]!='') // k=0
{
if (cnt1%)
{
ans += f[][cntw];
int tmp = getvar(,cntw);
flg += tmp;
if (tmp&&flg==) pos=i,k=;
}else
{
ans += f[][cntw];
int tmp = getvar(,cntw);
flg += tmp;
if (tmp&&flg==) pos=i,k=;
}
}
while (ans >= mod) ans -= mod;
}
if (flg>) cout<<"Ambiguous "<<ans<<endl;
else if (flg==) cout<<"Impossible"<<endl;
else PrintAns(pos,k);
} void initDp()
{
int i,j;
f[][] = ;
f[][] = ;
for ( i= ; i<maxn ; i++ )
for ( j= ; j< ; j++ )
{
f[j][i] = f[-j][i-]+f[j][i-];
while (f[j][i]>=mod) f[j][i] -= mod;
}
// for ( i=0 ; i<20 ; i++ ) printf("f[0][%d]=%I64d f[1][%d]=%I64d\n",i,f[0][i],i,f[1][i]);
} int main()
{
int cas,tt=;
freopen("test.txt","r",stdin);
// freopen("my.txt","w",stdout); scanf("%d",&cas);
initDp();
for ( tt= ; tt<=cas ; tt++ )
{
printf("Case #%d:\n",tt);
scanf("%s",g1);
scanf("%s",g2);
pretreat();
solv();
}
return ;
}

几组数据:

23

1?

1?

?

?

1?10

?0?0

110??????0?0?1???0?100??00?0?00000???0??????0?000??0?0?00?00?0??000?000???00000?0?0????0000000?0?0?0??00000??0???0??0??0?000?000?000000?0?0?0??0?000???0000?0?0000?0???????0??0?0?00????00?????0????00??
?1011?11??????1100??0?00?0?0???00????0?00???0000?0??0??0000000?0???0?0???????0?0???0??000??0???????00?00??0?0000??0?0???0?000??????00????0???0???0??000???00?0000?00???000???00????000?000000?0?00000?00
????0?????11?01??10????000??0??0??100??0??1??0?1?0?????010110?1?00??1?0??10????00??0?110?1????01?1????????000???01?110?1??1?01?1??0000???01?0?0111?0111101?010??0111?10?1??0??00?1????????00?????1?110??
?1??00???1?1??10?10?00?0?0??0?10?0?0????0?????0100?0???????1???1001??0011100????01???1???1??010??10110????00???00?0?10?10010?1010?0?0?01????000??1?0?1?1?110??0?011????????????0??10?00?01?0?01???0???11
?010000???????????00???0??00?0???00??000???0??0?0?000?0?0000???0000?0??0????0???0000?00?0?0??00?0?00?00?????0???0?0000?00000?0?000?00?????0??0?0???0?0???0?0??00?????000?0????0?0?0???0???000?00?0????00
?1??00?0000???000?0???0??0?0?0?0???000??00??0000?0??0?00??00?0?00????00000?0????0???000?0?00????0?????0????00??000?00?00??0??0?000?00?00??0000?0??0???0??0???00000???0?0?0??0??0?00???0000??0?0?0????0?0
??1???11?10?????00??0??10?10??1???1?11??0?0?000000??0?000?0??000??0???0????0??0?00???000????000???????000??00?0???00??00?0??0?00???00?0?00??000??000????00???0?00??000??00??00??00??00??0??????0?00???0?
?1??0?1?1?0?1??0000?0?1?001011?????11????11??0?0?0???0000?0?0?0?000000??0??00?????0?????0?0?0???0?000??0?0??00????0??0?0??0?00?0000?0??0?00?0??????0???0?0??0000??000?00?0?0000??0????0?00??0????0000??0
?10?1???0?1?0???????01?11?00?1011?????1?10?11????0?0??1??1?10??1010?011?10??1?0???001???0?1?0?111?1???111?0?1100000??01????1??????0??01110?1111????01??0?01100?????0?00?11?1000000?000?0???0?????0??0000
0?00???1????00?011?1?1?1?10?0?0?1???01?01011?001?0?00??10?0??????101??10?????10??1??110??0?00?11??1??01?1100?1???0010?1??001?1??1?00???110???1?1???0??001?1?00?11010????111??0?00?0???0????0?000????0000
???10??10?10??110??110?0??101?110?010100??001?????0??0?0???????0?0??0?0??????11?1?0?000?????????0??0????????00??1?000?01?1???11?0?0??????1?1?1010?01?0???0??1??1?1?1??0100??1?00??11
???00?1??1??0???11111????10?1??0????1??????1??0????0???10?????????00??1??????1?1?1??0?10?1??000?01??????01010?1??01?00?????000?10??1????????1???1?0?0????0?00?????1???0??1110?0??00?
?01?00???01?????11????10???1?00????00?00001110?1??1????00???1?01?0?00??????????1?0?01??100?0?0?111??0???????0??1??1?0????1?0???01???0?11??????0???0????
?????00????0?0???0???????10?????10??00?10???00???00???10?00?1001???1??0?10??1?1????011??????101????????01?0??10??1??01?0?????????001???0?10???01?011??1
?1?10??1?1?101?????0011??01?1??0??0?0??10???????????0?????1???1?01000?0?00???0??00???11?????0???1???0???1???1?1?0????1????01??0????11011?1?011??1?1?????????1??1?11??11?1?0???1??1?00?01??????????01
1?0?1???01101??11?0010??0???????0?001?1??000???100??1??01?00??111?1?1?1??1??0?10?????1????1???0??????????00??????10???1?1?110111?10?1????00????00?010??????????1??1?00??1001???01?1????00?11????????
???0?????0?001????0?
?????0?10??1?10?1?1?
?0???1???000?1?????0?????01????1?11????0?0???11???1?1??0?1????0??1?0?1??000?010?1????1?????00?1?00?111?111??0??0???0??0001?1???00?1?1?1???1????0???10?????0010?0
00?11???0?00001??????11???11?????10??1???11??01??1??0?1011001?101??01??1?10?10?01?1?1000??1?0??11?0?1????1???01???10?????????01???????0???0??01????001110?10????

上一篇:Error:(1, 1) error: illegal character: \65279解决方法


下一篇:llinux 环境安装编译 nginx (源码安装包)