08 2013 档案
摘要:思路:设: 方程为1*x1 ^ 1*x2 ^ 0*x3 = 0;0*x1 ^ 1*x2^ 1*x3 = 0;1*x1 ^ 0*x2 ^ 0*x3 = 0把每一列压缩成一个64位整数,因为x范围为 (0 1 2 3) 二进制位不超过2, 方程组行数不超过30 则用一个大于60位整数就能表示每一列的状态,然后枚举各列就可以了。如上面方程组第一列为 1 0 1 ,可写为a1 = 11 00 11, 假设x1取2, 则第一列 s1 = 10 10 10, s1&a1 = 10 00 10即为第一列的状态第二列 a2 = 11 11 00 设x2 = 1 则 s2 = 01 01 01, 第二列
阅读全文
摘要:思路:将15种分成5类:1.1和2为一类;2.3,4,5,6为一类;3.7,8,9,10为一类;4.11,12,13,14,15为一类;5.15为一类。比较各类的优先级,就会发现放置的顺序为5->2->4->3->1.代码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #define ll __int64 9 #define pi acos(-1.0) 10 #define MAX 50000 11 using namespace std; 12 int
阅读全文
摘要:思路:1.首先介绍下4次方的求和公式:S(n)=(6*n^5+15*n^4+10*n^3-n)/30.2.n太大直接求1~n-1中与n互质的数会超时,那么就转换下思路,求不与n互质的数;分析知道当某一个数不与n互质时,他的倍数也一定不与n互质,而且这个数与n具有公共的因子;为了去掉重复的很容易想到容斥原理。对于n=p1^a1*p2^a2*p3^a3……与n不互质的数=(p1+2*p1……)+(p2+2*p2……)-(p1*p2+2*p1*p2……)……;具体看代码: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #includ
阅读全文
摘要:搜索下就可以了……代码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 using namespace std; 7 int p[10][10],n,a[7],b[7]; 8 string str[10],s; 9 bool flag,vis[10],vis2[10]; 10 bool dfs2(int d) 11 { 12 int i,j; 13 if(d==n){ 14 i=j=0; 15 while(i>t; 68 while(t--){ 69...
阅读全文
摘要:思路:分析:假设取的牌顺序是一个序列,那么这种序列在末尾为1时是和取牌序列一一对应的,且是符合“游戏结束时牌恰好被取完”的一种情况。简证:1、在序列中,任一数 i 的后一个数 j 是必然要放在第 i 堆里的。而值为 i 的数有 a[i]个,所以在 i 后面的数也恰好a[i]个,所以a[i]个数被放到第 i 堆,符合题目约束条件。2、在序列中,由于游戏是从第一堆开始的,所以第一个数虽然没有前驱,但是他是放在第 1 堆的。所以如果 1 不为最后一个数,那么第一堆中必然有a[1]+1个数了,不行。3、序列中的最后一个数 记 i ,如果不为 1 ,那么值 i 就只有a[i]-1个后继了。4、结合2、3
阅读全文
摘要:同时进行,必须操作这就是Every-SG的特点同样在贾志豪的论文中有提到这种游戏:组合游戏略述——浅谈SG游戏的若干拓展及变形其中这个游戏特点不仅有必胜和必败,而且有时间长短的博弈,对于自己必胜的局面,希望步数越多越好,自己必败的局面,早点结束才有利。显得更加复杂。其中论文中提到,必胜当且仅当所有的单一游戏步数最大的为奇数。比较好理解,最大的为奇数,当然是先手赢,其它的都已经提前结束。在论文中有具体的证明和阐述。在这题中,可以发现如果X,Y,X>Y而且X/Y==1,则每次从X中取走Y,这步是固定的,但是当X/Y>=2的情况就不一样了。可以控制步数。在这个游戏中,由于是Every_S
阅读全文
摘要:有一种很有意思的游戏,就是有物体若干堆,可以是火柴棍或是围棋子等等均可。两个人轮流从堆中取物体若干,规定最后取光物体者取胜。这是我国民间很古老的一个游戏,别看这游戏极其简单,却蕴含着深刻的数学原理。下面我们来分析一下要如何才能够取胜。(一)巴什博奕(Bash Game):只有一堆n个物品,两个人轮流从这堆物品中取物,规定每次至少取一个,最多取m个。最后取光者得胜。 显然,如果n=m+1,那么由于一次最多只能取m个,所以,无论先取者拿走多少个,后取者都能够一次拿走剩余的物品,后者取胜。因此我们发现了如何取胜的法则:如果n=(m+1)r+s,(r为任意自然数,s≤m),那么先取者要拿走s个物品,如
阅读全文
摘要:SG函数!!代码如下: 1 #include 2 #include 3 #define I(x) scanf("%d",&x) 4 int map[1005][1005],sg[1005]; 5 int getsg(int n) 6 { 7 if(sg[n]!=-1) return sg[n]; 8 if(!map[n][0]) return sg[n]=0; 9 bool vis[1001];10 memset(vis,0,sizeof(vis));11 for(int i=1;i<=map[n][0];i++)12 vis[getsg...
阅读全文
摘要:这里有2种方法:方法一:求SG函数sg[i][j]:i表示1的个数,j表示合并操作的步数。这共有4种操作:1.消除一个1;2.减掉一个1;3.合并2个1;4.把1合并到另外不是1中。代码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 using namespace std; 9 int dp[60][50040];10 int dfs(int a,int b)11 {12 if(dp[a][b]!=-1) return dp[a][b];13 if(b==1) ...
阅读全文
摘要:思路:用拓展欧几里得算法可以得出原方程的一个解。然后就可以根据这个解判断在所给的区间里有几个解。由ax+by+c=0有ax+by=-c,两边取模b得到ax+by≡-c(modb)推出ax≡-c(modb)模线性方程有解当且仅当gcd(a,b)|-c,有解的情况下方程对模-c有d个不同的解,d=gcd(a,b)根据拓展欧几里得算法可以算出x0,y0使得d=a*x0+b*y0则x=x0*(-c/d),y=y0*(-c/d)为原方程ax+by+c=0的一个解则方程的所有解为x=x0*(-c/d)+i*(b/d),y=y0*(-c/d)-i*(a/d)计算所有的i使得解在所给区间内的个数即可。代码如下
阅读全文
摘要:思路:对于任何正整数x,其约数的个数记做g(x).例如g(1)=1,g(6)=4.如果某个正整数x满足:对于任意i(0求约数最多的数如果求约数的个数 756=2^2*3^3*7^1(2+1)*(3+1)*(1+1)=24基于上述结论,给出算法:按照质因数大小递增顺序搜索每一个质因子,枚举每一个质因子为了剪枝:性质一:一个反素数的质因子必然是从2开始连续的质数.因为最多只需要10个素数构造:2,3,5,7,11,13,17,19,23,29性质二:p=2^t1*3^t2*5^t3*7^t4.....必然t1>=t2>=t3>=....链接:http://acm.zju.edu.
阅读全文
摘要:思路:这题有个结论也可以自己归纳:对于给定的n,其约数用pi表示T(n)=T(p1)T(p2)……T(pn)T(n')其中T(n')是这个式子所独有的也就是T(n')=(x^n-1)/T(p1)/T(p2)……/T(pn)代码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #define MAX 1102 8 using namespace std; 9 struct pol 10 { 11 int bit[MAX],len; 12 void init(){mems...
阅读全文
摘要:思路:将条件转化为满足abc 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #define ll __int64 9 using namespace std;10 int main(){11 ll n,m,ans,i,j,k,v;12 int c=0;13 while(scanf("%I64d",&n)!=EOF){14 m=(ll)pow(n,1.0/3);//i=j=k15 ans=m;16 if((m+1)*(m+1)*(m+1...
阅读全文
摘要:思路:易知结果为∑(n-k)*C(n+k,k)*(p^(n+1)*q^k+q^(n+1)*p^k).注意不能直接算,注意点技巧!!!看代码代码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 using namespace std; 7 int main(){ 8 int n,i,j=0; 9 double p,q,ans1,ans2,m,c,pq,ans;10 while(scanf("%d%lf",&n,&p)!=EOF){11 q=1-p;12 pq=p*q;1...
阅读全文
摘要:思路:分析知道1 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #define ll __int64 9 #define M 201110 using namespace std;11 ll m,rr,kk,mi,n;12 ll pows(ll a,ll b)13 {14 ll ans=1;15 while(b){16 if(b&1) ans=ans*a;17 b>>=1;18 a*=a;19 }20 return ans;2...
阅读全文
摘要:思路:dp[i][j][k]表示满足前i个数,和为j,lcm为k的数目。设a为解的第i+1个数。 那么状态转移就为 dp[i+1][j+a][lcm(a,k)]+=dp[i][j][k]。但是由于三维开不了,所以用滚动数组。代码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #define ll __int64 9 #define pi acos(-1.0)10 #define MAX 100111 #define M 100000000712 using namespace
阅读全文
摘要:思路:1.求f[n];dp[i]表示i个连续相同时的期望则 dp[0]=1+dp[1] dp[1]=1+(5dp[1]+dp[2])/6 …… dp[i]=1+(5dp[1]+dp[i+1])/6 …… dp[n]=0可以求得f[n]=(6^n-1)/5.2.求h[n];dp[i]表示i个连续相同的1时的期望则 dp[0]=1+(5dp[0]+dp[1])/6 dp[1]=1+(5dp[0]+dp[2])/6 …… dp[i]=1+(5dp[0]+dp[i+1])/6 …… dp[n]=0可以求得h[n]=(6^(n+1)-6)/5.3.求g[m];dp[i]表示i个1时的期望则 dp[0]=
阅读全文
摘要:思路:易知L不能整除G时为0;将L/G质因数分解,对于其中的因子p,个数为cnt,则至少有一个包含p^cnt,至少有一个数不包含p;只有一个数包含p^cnt时,有C(3,1);有2个数包含p^cnt时,有C(3,1);有2个数包含p因子,其中一个是p^cnt,另外一个有cnt-1种,总共有(cnt-1)A(3,2).所以总共有6*cnt。代码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #define ll __int64 9 #define pi acos(-1.0)10
阅读全文
摘要:没什么说的裸线段树,注意细节就好了!!!代码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #define ll __int64 9 #define pi acos(-1.0) 10 #define MAX 100003 11 #define M 10007 12 #define lson i>1; 39 } 40 }T[MAX*4]; 41 void down(int i) 42 { 43 T[lson].Mul(T[i].mul); 44 ...
阅读全文
摘要:思路:由于m非常小,只有5。所以用dp[i]表示从位置i出发到达n的期望步数。那么dp[n] = 0dp[i] = sigma(dp[i + j] * p (i , i + j)) + 1 . (-m 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #define ll __int64 9 #define pi acos(-1.0)10 #define MAX 5000211 using namespace std;12 double a[MAX][11],p[MAX][11],consts[MAX],q.
阅读全文
摘要:思路:刚开始用STL中的栈,一直RE……,之后改为手动模拟栈操作,在注意点细节就可以了!!!代码如下: 1 #include 2 #include 3 #include 4 #define M 1000001 5 using namespace std; 6 int A[M],B[M],a[M],s[M],cur,x,q,l,r; 7 char c; 8 int main() 9 {10 while(scanf("%d",&q)!=EOF){11 l=r=1;12 while(q--){13 scanf("%s",&c);14 ...
阅读全文
摘要:思路:▶ 设 win(i,x,y) 表示当前可以买的物品是 i,先手有 x 元,后 手有 y 元时,先手是否必胜 ▶ win(i,x,y) ⇐⇒∃j((j > i)∧(x ≥ si−sj)∧¬win(j,y,x−si +sj)) ▶ 其中 si = Ci + Ci+1 +···+ CN ▶ 注意到 x + y = A + B−s1 + si,即 win(i,x) := win(i,x,y)▶ win(i,x) =⇒ win(i,x + 1) ▶ 设 m(i) = min{x : win(i,x)},则 ¬win(i,x) ⇐⇒ x ≤ m
阅读全文
摘要:思路:对于给定的n,s(i)即将n分解为i个数的组合数,也就是在n-1个位置插入i-1个板即C(n-1,i-1);∑S=2^(n-1);phi(1000000007)=1000000006;对于n>=phi,有a^n%c=a^(n%phi(c)+phi(c))%c。代码如下: 1 #include 2 #include 3 #define ll __int64 4 #define mod 1000000007 5 #define phi 1000000006 6 char s[100002]; 7 ll pow(ll a,ll b) 8 { 9 ll ans=1;10 whil...
阅读全文
摘要:思路:由于c[i]要么是1,要么是2.所以当c[i]中没有1的时候就不可能得到奇数;再就是如果m 2 #include 3 int main() 4 { 5 int n,q,i,a,mm,b; 6 while(scanf("%d%d",&n,&q)!=EOF) 7 { 8 for(i=1;i<=n;i++){ 9 scanf("%d",&a);10 }11 b=0;12 for(i=1;i<=n;i++){13 scanf("%d",&a);14 ...
阅读全文
摘要:简单的SG函数应用!!!代码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 using namespace std; 9 int sg[10001],k,a[101];10 int getsg(int x)11 {12 if(sg[x]!=-1) return sg[x];13 if(x-a[0]=0;i++){17 vis[getsg(x-a[i])]=1;18 }19 for(int i=0;;i++)20 i...
阅读全文
摘要:思路:如果负数的个数为偶数则不必改变,为奇数就将最大负数变为正;对于正数,尽量将1,2变为3即可。代码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #include 9 #include 10 #define Maxn 2010 11 #define LL __int64 12 #define MM 1000000007 13 using namespace std; 14 priority_queue les; 15 priority_queue ,gre...
阅读全文
摘要:题意:有n个人爬山,山顶坐标为0,其他人按升序给出,不同的坐标只能容纳一个人(山顶不限),Alice和Bob轮流选择一个人让他移动任意步,但不能越过前面的人,且不能和前面一个人在相同的位置。现在有一个人是king,给出king是哪个人(id),谁能将国王移动到山顶谁胜。解题思路:先考虑简化版,没有king,谁先不能移动谁输掉。和阶梯博弈类似http://blog.csdn.net/longshuai0821/article/details/7793043。根据人数的奇偶性:把人从上顶向下的位置记为a1,a2,...an, 如果为偶数个人,则把a(2i-1)和a(2i)之间的距离-1(空格数)当
阅读全文
摘要:打表找规律:当n为质数是,GCD(n)=n;当n为质数k的q次方时,GCD(n)=k;其他情况,GCD(n)=1.代码如下: 1 #include 2 #include 3 #include 4 #define ll long long 5 #define M 1000001 6 using namespace std; 7 ll a[M]; 8 int prime[79000],cnt; 9 bool f[M];10 int fac(int n)11 {12 for(int i=0;i<cnt&&prime[i]*prime[i]<=n;i++){13 if(n%
阅读全文
摘要:K倍动态减法游戏!!!链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4683代码如下: 1 #include 2 #include 3 #include 4 #define ll long long 5 using namespace std; 6 ll a[3000000],b[3000000]; 7 int main() 8 { 9 int i,j,t,k;10 ll n,ans;11 scanf("%d",&t);12 while(t--){13 scanf("%...
阅读全文
摘要:思路:这就是K倍动态减法游戏,可以参考曹钦翔从“k倍动态减法游戏”出发探究一类组合游戏问题的论文。首先k=1的时候,必败态是2^i,因为我们把数二进制分解后,拿掉最后一个1,那么会导致对方永远也取不完,我们可以拿到最后一个1.k=2的时候,必败态是斐波那契数列,因为任何一个整数n都可以写成两项斐波那契数的和,所以我们拿掉1,对方永远取不完高两位的数。k的时候我们必须构造数列,将n写成数列中一些项的和,使得这些被取到的项的相邻两个倍数差距>k 那么每次去掉最后一个1 还是符合上面的条件。设这个数列已经被构造了i 项,第 i 项为a[ i ],前 i 项可以完美对1..b[ i ] 编码使得
阅读全文
摘要:思路:求必胜区间和必败区间!1-9 先手胜10-2*9后手胜19-2*9*9先手胜163-2*2*9*9后手胜……易知右区间按9,2交替出现的,所以每次除以18,直到小于18时就可以直接判断了。代码如下: 1 #include 2 int main() 3 { 4 double n; 5 while(scanf("%lf",&n)!=EOF){ 6 while(n>18) n/=18; 7 if(n<=9) puts("Stan wins."); 8 else puts("Ollie wins."); 9 }10
阅读全文
摘要:思路:主要考虑求1-n中与p互质数的和。直接不好求解,反着来!求1-n中与p不互质的数的和。由于p=p1^e1*p2^e2……所以有容斥原理来解决。代码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #define ll __int64 8 using namespace std; 9 mapmm; 10 map::iterator it; 11 bool f[1000]; 12 int factor[1000],prime[1000],cnt,num,cn; 13 ll an[4...
阅读全文
摘要:思路:构造矩阵a[i]*b[i]=ax*bx*a[i-1]*b[i-1]+ax*by*a[i-1]+ay*bx*b[i-1]+ay*by代码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #define ll __int64 8 #define mod 1000000007 9 #define phi 100000000610 using namespace std;11 struct ma12 {13 ll a[5][5];14 };15 ma mul(ma a,ma b)16 {17 ...
阅读全文
摘要:思路:容易发现二进制表示的数的最低位规律是01010101……;接着是001100110011……;接着是:0000111100001111……这样我们发现每一位的循环节是2^(i+1),前2^i是0,后面的是1.这样就可以算出每一位1出现的次数。代码如下: 1 #include 2 #include 3 #include 4 #include 5 #define ll __int64 6 using namespace std; 7 ll a[35]={1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384, 8 32768,65536,
阅读全文
摘要:思路:设期望值为s,前m个是再来一次机会,则有s=(a[1]+s)/n+(a[2]+s)/n+……+(a[m]+s)/n+a[m+1]/n……化简:(n-m)s=sum当sum=0时,为0;当n==m时,为inf;否则为sum/(n-m).代码如下: 1 #include 2 #define I(x) scanf("%d",&x) 3 int main() 4 { 5 int n,m,t,sum; 6 while(I(n)!=EOF){ 7 sum=0; 8 for(int i=0;i<n;i++){ 9 I(t);10 ...
阅读全文
摘要:没什么好方法,只能用dfs了。代码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #define I(x) scanf("%d",&x) 8 using namespace std; 9 int a[20],n,ans;10 set > p;11 void dfs(int pos,int sum1,int sum2,int sum3)12 {13 int i,j,k;14 if(pos==n){15 if(sum2==0||sum3==0) return ;16 .
阅读全文
摘要:动态规划,主要是用单调性求区间的最小期望。代码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #include 9 #define MAX 100410 #define inf 1q;14 struct node15 {16 int x;17 double p;18 }an[MAX];19 void init(int m)20 {21 int i,j;22 for(i=0;i::iterator it=q.begin();it!=q.end();...
阅读全文
摘要:思路:将点按值从小到大排序,询问按h从小到大排序。在建立线段树,按h的大小更新树并得到该次查询的结果!代码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #define MAX 100005 8 #define I(x) scanf("%d",&x) 9 #define lson step>1;38 built(lson,l,m);39 built(rson,m+1,r);40 }41 void update(int step,int pos)42 {43 T[st
阅读全文
摘要:高斯消元求期望!!将n时间点构成2*(n-1)的环,每一点的期望值为dp[i]=dp[i+1]*p1+dp[i+2]*p2+……+dp[i+m]*pm+1.这样就可以多个方程,利用高斯消元求解。代码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #include 9 #define MAX 200 10 #define eps 1e-8 11 using namespace std; 12 double p[MAX],a[MAX][MAX],ans[MAX];...
阅读全文
摘要:由于要输出方案,变得复杂了。数据不是很大,首先打表,所有whthoff 的奇异局势。然后直接判断是否为必胜局面。如果必胜,首先判断能否直接同时相减得到。这里不需要遍历或者二分查找。由于两者同时减去一个数,他们的差不变,而且ak=k*(sqrt(5)+1),bk=ak+k;则可以通过二者的差直接定位,然后判断。对于另外一种情况,其中一个减去某个数,得到奇异局势,则是分情况二分查找。注意一些细节代码如下: 1 #include 2 #include 3 #include 4 #define M 1000002 5 using namespace std; 6 int a[M/2],b[M/2],c
阅读全文
摘要:求可行的方案数!!代码如下: 1 #include 2 int a[120]; 3 int main(){ 4 int n,m; 5 while(scanf("%d",&n)&&n){ 6 m=0; 7 for(int i=0;i<n;i++){ 8 scanf("%d",&a[i]); 9 m^=a[i];10 }11 int cnt=0;12 for(int i=0;i<n;i++)13 if((m^a[i])<a[i])1...
阅读全文
摘要:思路:当n1时,先手操作之后必定形成链,后手操作后形成二条一样的链,之后,先手怎么操作,后手就怎么操作,则后手必胜。代码如下: 1 #include 2 int main(){ 3 int t,k=0,n,m; 4 scanf("%d",&t); 5 while(t--){ 6 scanf("%d%d",&n,&m); 7 printf("Case %d: %s\n",++k,((m==1&&(n&1))||n<=m)?"first":"second&
阅读全文
摘要:离线+分块!!思路:序列a[1],a[2],a[3]……a[n]num[i]表示区间[L,R]中是i的倍数的个数;euler[i]表示i的欧拉函数值。则区间的GCD之和sum=∑(C(num[i],2)*euler[i]).当增加一个数时,若有约数j,则只需加上num[j]*euler[j],之后再num[j]++;反之亦然!!代码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #define ll __int64 9 #define pi acos(-1.0...
阅读全文
摘要:理解题意:连续的数分为一组,每次判断下就可以了!!代码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #define ll __int64 9 #define pi acos(-1.0)10 #define MAX 10010511 using namespace std;12 int R,L,an[MAX],ans[MAX],res;13 bool vis[MAX];14 struct node15 {16 int x,y,l,p;17 }q[MAX];18 bool...
阅读全文
摘要:离线+分块将n个数分成sqrt(n)块。对所有询问进行排序,排序标准: 1. Q[i].left /block_size 2 #include 3 #include 4 #include 5 #include 6 using namespace std; 7 #define N 200100 8 typedef long long ll; 9 ll a[N], cnt[N*5], ans[N], res;10 int L, R;11 12 struct node {13 int x, y, l, p;14 } q[N];15 bool cmp(const node &x,...
阅读全文
摘要:这是一题简单的博弈论!!所有的空白+边界的数字(个数为n)为一堆,容易推出其SG函数值为n%2+1;其他所有的数字(个数为m)的SG值为m%2。再就是用dfs将空白部分搜一下即可!(注意细节)代码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #define MAX 1005 9 #pragma comment(linker,"/STACK:1024000000,1024000000") 10 using namespace std; 11 int vis[
阅读全文
摘要:思路:首先给出一个结论,就是最多用两个数就可以表示任何数的倍数。证明 :对于一个数字a,可以构造出的数字有a,aa,aaa,aaaa,aaaaa,……每一个数对于n都有一个余数,余数最多有n个,根据鸽巢原理,前n+1个数中,必然有两个余数相等那么二者之差,必定为n的倍数,形式为a……a0……0。有这个结论,就简单了先枚举一个数,然后枚举两个数,BFS即可代码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #include 9 #define MAX 1000110 using
阅读全文
摘要:数学题,找循环节!!首先g(g(g(n)))=g(x) mod 1e9+7 则可知x有循环节1e9+7;之后x=g(g(n)),则可算出g(n)的循环节,在算出n的循环节就可以了!!代码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #define ll __int64 9 #define mod1 100000000710 #define mod2 22222222411 #define mod3 18312012 #define mod4 24013 using names
阅读全文
摘要:看了解题报告才知道怎么做!!题意:有 N 堆石子和 M 个石子回收站,每回合操作的人可以选择一堆石子,从中拿出一些 放到石子回收站里(可以放进多个回收站,每个回收站可以使用无数次),但每个石子回收站每次 只能接收特定数量的石子。不能操作的输。如果有人操作完之后,有任意一堆石子无法完全回收, 那么他直接输。 一个显然的结论是,每个游戏的 SG 值就是用 M 个回收站,完全回收这堆石子可行的最大 操作次数。由于最大的 Bi 比较小,立方暴力背包即可(比较显然的是,maxBi2 以上的周期是 minBi)。而最大也就是10000,所以可以直接暴力求解sg值,找到最大操作次数。ps:看到有人竟然仅仅用
阅读全文
摘要:博弈论+二分!后一人会尽量选前一人切小的一块切!!代码如下: 1 #include 2 #include 3 #define I1(x) scanf("%d",&x) 4 #define I2(x,y) scanf("%d%d",&x,&y) 5 int main(){ 6 int n,t,k=0,a,b; 7 __int64 m1,m2; 8 I1(t); 9 while(t--){10 I1(n);11 m1=m2=0;12 for(int i=1;i1&&b>1){15 a>>...
阅读全文
摘要:思路: 其本质为阶梯博弈; 阶梯博弈:博弈在一列阶梯上进行,每个阶梯上放着自然数个点,两个人进行阶梯博弈...每一步则是将一个集体上的若干个点(>=1)移到前面去,最后没有点可以移动的人输;在本题中 1,3,4 的状态不能转移到其他状态; 其他每个状态皆可转移; 且位置特定, 如 2->1 , 5->4, 6->3, 7->2 , 8->1 9->6.....其本质我们有N级阶梯,现在要在 %3 的余数间转移, 0->0, 1->2, 2->1; 其最后的结果为1, 3, 4; 那么他们的转移的步数的奇偶性也会确定;我们只要选择步数为
阅读全文
摘要:找规律的博弈论!!很容易发现当n,m都为奇数时先手必败!代码如下: 1 #include 2 #include 3 #define I(x,y) scanf("%d%d",&x,&y) 4 int main(){ 5 int m,n; 6 while(I(n,m)&&(n+m)){ 7 if(!(n&1)||!(m&1)) puts("Wonderful!"); 8 else puts("What a pity!"); 9 }10 return 0;11 }View Code
阅读全文
摘要:很显然的nim游戏的变形,很好找规律先手败:2,3,5,8,13……其他先手胜。即满足菲波拉数列。代码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #define ll __int64 9 #define pi acos(-1.0)10 #define MAX 5000011 #define I(x) scanf("%d",&x)12 using namespace std;13 int f[44];14 int main(){15 int i,n
阅读全文
摘要:数学题!从M到1计算,在计算i的时候,算出原序列是i的倍数的个数cnt;也就是将cnt个数中的cnt-(n-k)个数变掉,n-cnt个数变为i的倍数。且i的倍数为t=m/i;则符合的数为:c[cnt][n-k]*t^(n-cnt)*(t-1)*(cnt-(n-k)).这样得到的是所有i的倍数,还要减去2*i,3*i……代码如下: 1 #include 2 #include 3 #define M 1000000007 4 #define MM 300001 5 #define ll __int64 6 #define I(x) scanf("%d",&x) 7 in
阅读全文
摘要:这个分区间:1 2 #include 3 #include 4 #include 5 #include 6 #define in(x) scanf("%d",&x) 7 using namespace std; 8 int main(){ 9 int n,t,ans,k,p,q;10 while(cin>>n>>p>>q){11 if(n%(p+q)>=1&&n%(p+q)<=p)12 cout<<"LOST"<<endl;13 else cout<&l
阅读全文
摘要:这题是Lasker’s Nim.Clearly the Sprague-Grundy function for the one-pile game satisfies g(0) = 0 and g(1) = 1. The followers of 2 are 0, 1 and (1,1), with respective Sprague-Grundy values of 0, 1, and 1⊕1 = 0. Hence, g(2) = 2. The followers of 3 are 0, 1, 2, and (1,2), with Sprague-Grundy values 0, 1, 2,
阅读全文
摘要:详见:http://www.cnblogs.com/xin-hua/p/3255985.html约束条件6代码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #define in(x) scanf("%d",&x) 7 using namespace std; 8 int a[101]; 9 int main(){10 int n,i,j,t,ans,num,cnt,k;11 while(in(n)!=EOF){12 if(n==0){13 puts("Yes")...
阅读全文
摘要:翻硬币游戏一般的翻硬币游戏的规则是这样的:N枚硬币排成一排,有的正面朝上,有的反面朝上。我们从左开始对硬币按1到N编号。第一,游戏者根据某些约束翻硬币,但他所翻动的硬币中,最右边那个硬币的必须是从正面翻到反面。例如,只能翻3个硬币的情况,那么第三个硬币必须是从正面翻到反面。如果局面是正正反,那就不能翻硬币了,因为第三个是反的。第二,谁不能翻谁输。有这样的结论:局面的SG值为局面中每个正面朝上的棋子单一存在时的SG值的异或和。即一个有k个硬币朝上,朝上硬币位置分布在的翻硬币游戏中,SG值是等于k个独立的开始时只有一个硬币朝上的翻硬币游戏的SG值异或和。比如THHTTH这个游戏中,2号、3号、6号
阅读全文
摘要:记忆化搜索+概率DP代码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #define ll __int64 9 #define pi acos(-1.0)10 #define MAX 5000011 using namespace std;12 int c[101],n,ff;13 double dp[100001];14 double solve(int f)15 {16 if(dp[f]>0) return dp[f];17 dp[f]=0;18 ...
阅读全文
摘要:题意:1-n个位置中,每个位置填一个数,问至少有l个数是相同的概率。可以转化求最多有l-1个数是相同的。dp[i][j]表示前i个位置填充j个位置的方案数,并且要满足上面的条件。则:dp[i][j]=∑dp[i-1][j-k]*c[m-j+k][k];也就是看第i个数,可以不填,填一个位置,两个位置······这样累加过来。代码如下: 1 import java.math.*; 2 import java.util.*; 3 public class Main { 4 public static void main(String ar
阅读全文
摘要:思路:两个数a和b,总会出现的一个局面是b,a%b,这是必然的,如果a>=b&&a=2的话,先手可以选择由谁面对b,a%b这样的局势,先手在a/b>=2的局面必胜代码如下: 1 #include 2 #include 3 #include 4 #include 5 using namespace std; 6 int main(){ 7 int a,b,t; 8 while(scanf("%d%d",&a,&b)!=EOF&&(a+b)){ 9 if(a=2) break;13 t=a;14 a=b;15 ...
阅读全文
摘要:方法一:找规律,很容易知道1 #include2 int main(){3 int n;4 while(scanf("%d",&n)!=EOF){5 puts(n%3==0?"Cici":"Kiki");6 }7 return 0;8 }View Code 方法二:简单的sg函数应用代码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #define ll __int64 9 #define pi acos(-1
阅读全文
摘要:看到这题时,当时还不会做,也没搞懂sg函数,于是狠狠的钻研了下博弈论,渐渐的知道了sg函数……现在在来做这题就很容易了,1A打表容易发现在80左右的时候就出现循环节了代码如下: 1 #include 2 #include 3 #define in(x) scanf("%d",&x) 4 int sg[101]; 5 bool vis[101]; 6 int getsg(int x) 7 { 8 if(sg[x]>=0) return sg[x]; 9 memset(vis,0,sizeof(vis));10 for(int i=0;i=100){19 i...
阅读全文
摘要:很容易想到三分法求解,不过要分别在0-pi,pi-2pi进行三分。另外也可以直接暴力枚举……代码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #define ll __int64 9 #define pi acos(-1.0) 10 #define MAX 50000 11 using namespace std; 12 struct point 13 { 14 double x,y; 15 point(double _x=0,double ...
阅读全文
摘要:思路:dp[i][j][k]表示在点(i,j)处能量的差值为k的方案数转移的时候把差值取相反数就实现轮流了代码如下: 1 #include 2 #include 3 #include 4 #define MAX 480 5 #define mod 1000000007 6 using namespace std; 7 int dp[MAX][MAX][11]; 8 char str[MAX][MAX]; 9 int main(){10 int t,i,j,k,c=0,n,m,t1,t2,ans;11 scanf("%d",&t);12 while(t--){13 .
阅读全文
摘要:水题……代码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #define ll __int64 9 #define pi acos(-1.0)10 #define MAX 100111 using namespace std;12 struct xx13 {14 int id;15 char name[20];16 int value;17 bool use;18 }an,p[1001];19 bool cmp(const xx &a,cons...
阅读全文
摘要:构造SG函数:sg[i]表示2*i的sg值!!代码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #define ll __int64 9 #define pi acos(-1.0)10 #define MAX 500011 using namespace std;12 int an[2][MAX],sg[MAX];13 bool vis[MAX];14 int getsg(int x)15 {16 int i;17 if(sg[x]>=0) return sg...
阅读全文
摘要:简单博弈问题(巴什博弈-Bash Game)巴什博弈:只有一堆n个物品,两个人轮流从这对物品中取物,规定每次至少取一个,最多取m个,最后取光着得胜。很容易想到当n%(m+1)!=0时,先取者必胜,第一次先拿走n%(m+1)个,以后每个回合都保持两人拿走的物品总和为m+1即可。这个游戏还可以有一种变相的玩法:两个人轮流报数,每次至少报一个,最多报10个,谁能报到100者胜。此题可以把每堆石头的取法看作是一个BashGame,这样只需将每组石头按照BashGame的取法判断,然后将n堆石头做异或,如果异或的结果不为0,则老师获胜,否则Agrael取胜。代码如下: 1 #include 2 #inc
阅读全文
摘要:那么对于这题对于每一堆,放石子放满就想当于满的时候取s-c个,反向只是让我理解题意更深。首先我们知道(S,S)这个局面是必败局面。对于每一堆能加的数量有限,而当c的值(大于或者等于)D=sqrt(s) 或者 D=sqri(s)+1的时候就可以一次完成,就是说可以从当前局面到达(S,S)的局面,所以当前局面是必胜局面。而这种情况下,你能造成的局面有集合A={0,1,2,...,s-c-1};因为你可以去s-c,s-c-1,s-c-2,.....,1;那么对应mex(x)函数(即A中未出现的最小的一个数字),那么自然该局面的SG值就是s-c了;另外当c的值小于D的时候,是不可能一下子加满的,因为c
阅读全文
摘要:水题,转化Nim代码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #define ll __int64 9 #define pi acos(-1.0)10 #define MAX 5000011 using namespace std;12 int m,t,ans;13 int main(){14 while(scanf("%d",&m)&&m){15 ans=0;16 while(m--){17 scanf("...
阅读全文
摘要:很简单的博弈论问题,可以转化为Nim代码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #define ll __int64 9 #define pi acos(-1.0)10 #define MAX 5000011 using namespace std;12 int n,m,t,j,ans;13 int main(){14 while(scanf("%d%d",&n,&m)!=EOF){15 ans=0;16 for(int i=0;..
阅读全文
摘要:找sg值,可以选择暴力,也可以利用sg值的特点简化。暴力就跟取石子一样,没什么差别,DFS搞定。把矩阵看成一个字符串,字符串就是一个状态。其实我们也可以不暴力求sg值,因为只要当前状态能到达一个sg值为0的点,当前状态就是必胜点。若当前点到达的所有状态都是必胜的,那么当前点就是必败点。所以当我们到达必胜点时,就必须转换当前状态继续递归找sg值。代码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #define ll __int64 9 #define pi acos(-1.0)
阅读全文
摘要:题意:原来袋子里有w只白鼠和b只黑鼠龙和王妃轮流从袋子里抓老鼠。谁先抓到白色老师谁就赢。王妃每次抓一只老鼠,龙每次抓完一只老鼠之后会有一只老鼠跑出来。每次抓老鼠和跑出来的老鼠都是随机的。如果两个人都没有抓到白色老鼠则龙赢。王妃先抓。问王妃赢的概率。解析:设dp[i][j]表示现在轮到王妃抓时有i只白鼠,j只黑鼠,王妃赢的概率明显 dp[0][j]=0,0 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #define ll __int64 9 #define pi acos(-1.0)10 #define
阅读全文
摘要:java水过……代码如下: 1 import java.math.*; 2 import java.util.*; 3 public class Main { 4 public static void main(String arg[]){ 5 BigInteger n,ans,sum; 6 Scanner cin = new Scanner(System.in); 7 int k,t=cin.nextInt(); 8 while(t-->0){ 9 n=cin.nextBigInteger...
阅读全文
摘要:概率DP,从前往后递推就可以了!!代码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 using namespace std; 9 double dp[2][202],ans;10 int main(){11 int n,m,t,i,j,k,l,r,w;12 while(cin>>n>>m>>l>>r){13 if(n==0&&m==0&&l==0&&r==0) break;14 m
阅读全文
摘要:简单的概率DP!!!结果=所以的情况-所以满足且 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #define ll __int64 9 #define pi acos(-1.0)10 #define MAX 100111 using namespace std;12 double p[MAX][32],dp[50][32],s[MAX][32],p1,p2;13 int main(){14 int n,m,t,i,j,k;15 while(cin>>m>>t>>n){
阅读全文
摘要:这个解题报告讲的很详细了!!!代码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #define ll __int64 9 #define pi acos(-1.0)10 #define MAX 100001011 #define mod 100000000712 using namespace std;13 int an[MAX];14 ll s,ans,temp;15 ll pows(ll a,ll b){16 ll ans=1;17 while(b){18...
阅读全文
摘要:思路: 对于一条边来说, 如果拿了一个点, 说明已经拿了该边的一半权值。如果某边的两个的顶点分别是不同的人。 那么差值还是不变的。如果某边的两个顶点分别是同一个人。 那么和值也不变。所以我们可以把一个边分解到两个顶点上,然后依次Alice 取最大,Bob 取次大。 因为 他们都是绝顶聪明的。代码如下: 1 #include 2 #include 3 #include 4 using namespace std; 5 double d[100001],ans; 6 int main(){ 7 int n,m,i,u,v,w; 8 while(scanf("%d%d",&
阅读全文
摘要:水题一枚……代码如下: 1 #include 2 #include 3 using namespace std; 4 int s[100001],t; 5 int main(){ 6 int n,m,i,j,ans; 7 while(scanf("%d%d",&n,&m)!=EOF){ 8 ans=0; 9 for(i=1;i=1&&i>ans;i--)14 for(j=1;j+i-1<=n;j++)15 if((s[i+j-1]-s[j-1])%m==0){16 ans=m...
阅读全文
摘要:思路:反状态压缩——把数据转换成20位的01来进行运算因为只有20位,而且&,|,^都不会进位,那么一位一位地看,每一位不是0就是1,这样求出每一位是1的概率,再乘以该位的十进制数,累加,就得到了总体的期望。对于每一位,状态转移方程如下:f[i][j]表示该位取前i个数,运算得到j(0或1)的概率是多少。f[i][1]=f[i-1][1]*p[i]+根据不同运算符和第i位的值运算得到1的概率。f[i][0]=f[i-1][0]*p[i]+根据不同运算符和第i位的值运算得到0的概率。初始状态:f[0][0~1]=0或1(根据第一个数的该位来设置)每一位为1的期望 f[n][1]这题只要知
阅读全文
摘要:思路:dp[i]表示当前在已经投掷出i个不相同/相同这个状态时期望还需要投掷多少次对于第一种情况有:dp[0] = 1+dp[1]dp[1] = 1+((m-1)*dp[1]+dp[2])/mdp[i] = 1+((m-1)*dp[1]+dp[i+1])/m……dp[n] = 0可以得到:dp[n-1]=m*dp[n]+1所以dp[0]=(m^n-1)/(m-1)也即是第一种的答案!对于第二种情况有:dp[0]=1+dp[1]dp[1]=1+(dp[1]+(m-1)*dp[2])/mdp[i]=1+(dp[1]+……+dp[i]+(m-i)*dp[i+1])/m……dp[n]=0令d[i]=d
阅读全文
摘要:思路:将所有的字符都变成I,判断I的个数是否是2的幂。设I的个数为a,U的个数为b则有a+3b+6x=2^K是否有解,也就是a+3b不能是3的倍数。代码如下: 1 #include 2 #include 3 char str[1000001]; 4 int main(){ 5 int i,t,len,num,sum; 6 scanf("%d",&t); 7 while(t--){ 8 scanf("%s",&str); 9 if(strcmp(str,"MI")==0){10 puts("Yes")
阅读全文
摘要:思路:用一个数组index[]存放a的下标,初始化令a[i]=c[i]=index[i]=i;假设当前处理的i,初始时令cur=i;j为大于i的任意值。每次操作找a[l]=c[cur]-b[cur]。若cur==l则结束;否则交换a[l]和a[cur]的值以及下标。若l>i,那么结束;否则令cur=l,然后交换c[cur]和c[j],继续处理知道该轮结束。代码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #include 9 #define ll __int6410 #
阅读全文
摘要:五角数定理!!可以参考这个http://www.cnblogs.com/xin-hua/p/3242428.html代码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #define ll __int64 9 #define pi acos(-1.0)10 #define MAX 10000111 using namespace std;12 const int mod=1000000007;13 int an[MAX],n,t,k;14 void init(){15 ...
阅读全文
摘要:简单的概率DP入门题代码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #define ll __int64 9 #define pi acos(-1.0)10 #define MAX 100311 using namespace std;12 struct point13 {14 double c,b,r;15 }p[MAX][MAX];16 double dp[MAX][MAX];17 int main(){18 int n,m,i,j;19 whi...
阅读全文
摘要:题意: 有n个房间,由n-1条隧道连通起来,实际上就形成了一棵树, 从结点1出发,开始走,在每个结点i都有3种可能: 1.被杀死,回到结点1处(概率为ki) 2.找到出口,走出迷宫 (概率为ei) 3.和该点相连有m条边,随机走一条 求:走出迷宫所要走的边数的期望值。思路: 设 E[i]表示在结点i处,要走出迷宫所要走的边数的期望。E[1]即为所求。 叶子结点:有3种情况:kill;exit(成功出去的期望为0) ;回到父节点。 E[i] = ki*E[1] + ei*0 + (1-ki-ei)*(E[father[i]] + 1); = ki*E[1] + (1-ki-ei)*E[fath.
阅读全文
摘要:思路:分析题意,可以得到如下递推关系:dp[i][j]表示i个人排队,Tomato在j位置的概率j=1 时,dp[i][j] = p1*dp[i][j]+p2*dp[i][i]+p4;2 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #define ll __int64 9 #define pi acos(-1.0)10 #define MAX 200511 using namespace std;12 double dp[MAX][MAX],c[MAX];13 int main(){14 int...
阅读全文
摘要:思路:简单的概率DPdp[i]表示从i到n的期望步数:当i没有飞机时dp[i]=∑p[k]*p[i+k]+1;当i有飞机时dp[i]=dp[fly[i]].代码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #define ll __int64 9 #define pi acos(-1.0)10 #define MAX 10000511 using namespace std;12 double p[MAX];13 int fly[MAX];14 int main(){15 .
阅读全文
摘要:思路:这题的递推方程有点麻烦!!dp[i]表示分数为i的期望步数,p[k]表示得分为k的概率,p0表示回到0的概率:dp[i]=Σ(p[k]*dp[i+k])+dp[0]*p0+1设dp[i]=A[i]*dp[0]+B[i]带入的:dp[i]=∑(pk*A[i+k]*dp[0]+pk*B[i+k])+dp[0]*p0+1 =(∑(pk*A[i+k])+p0)dp[0]+∑(pk*B[i+k])+1; 明显A[i]=(∑(pk*A[i+k])+p0) B[i]=∑(pk*B[i+k])+1 先递推求得A[0]和B[0]. 那么 dp[0]=B[0]/(1-A[0]);链接:http://acm.
阅读全文
摘要:思路:仔细读懂题意。dp[i][j]表示第i个bug,第j个子系统;那么状态转移就有4种可能:dp[i][j],概率是p1=i/n*j/s;dp[i+1][j],概率是p2=(n-i)/n*j/s;dp[i][j+1],概率是p3=i/n*(s-j)/s;dp[i+1][j+1],概率是p4=(n-i)/n*(s-j)/s;那么就有:dp[i][j]=p1*(dp[i][j]+1)+p2*(dp[i+1][j]+1)+p3*(dp[i][j+1]+1)+p4*(dp[i+1][j+1]+1) //注意这里加1是因为本次操作花费一天=p1*dp[i][j]+p2*dp[i+1][j]+p3*dp
阅读全文
摘要:容易推出递推关系f[n]=p*f[n-1]+(1-p)*f[n-2];可以通过矩阵快速幂求得第n步的概率。对于给出的点an[1],an[2]……可以分段求出:1~an[1];an[1]+1~an[2];……这样算出到达雷点的概率,然后用1减去就是成功通过雷点的概率,最后运用将每段成功通过的概率相乘即可!!代码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #define ll __int64 9 #define pi acos(-1.0)10 #define MAX 10000
阅读全文
摘要:思路:五边形数定理!!!五边形数定理是一个由欧拉发现的数学定理,描述欧拉函数展开式的特性。欧拉函数的展开式如下:亦即欧拉函数展开后,有些次方项被消去,只留下次方项为1, 2, 5, 7, 12, ...的项次,留下来的次方恰为广义五边形数。若将上式视为幂级数,其收敛半径为1,不过若只是当作形式幂级数(formal power series)来考虑,就不会考虑其收敛半径。欧拉函数的倒数是分割函数的母函数,亦即:其中为k的分割函数。上式配合五边形数定理,可以得到考虑项的系数,在 n>0 时,等式右侧的系数均为0,比较等式二侧的系数,可得因此可得到分割函数p(n)的递归式以n=10为例这就是所
阅读全文
摘要:刚开始我也不知道怎么做,后来慢慢就推出来了……对于样例2 1 0,结果是2/32 2 0,结果是4/53 2 0,结果是6/73 2 1,结果是9/14=6/7*3/4……之后就会发现每一项都是d/(d+1);而d又是怎样来的呢?上面的d分别是2*1;2*2;3*2,3*1……所以规律就出来,哈哈……看代码: 1 #include 2 #include 3 #include 4 #include 5 #include 6 using namespace std; 7 int main() 8 { 9 int t,n,p,k,i;10 double ans;11 cin>...
阅读全文
摘要:思路:1表示竖着的下半部分,0表示其他情况。dp[i][j]表示第i行第j种状态满足的数目。代码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #define ll __int64 9 #define pi acos(-1.0)10 #define MAX 1211 using namespace std;12 ll dp[MAX][(1>=1;//右移25 }26 if(w%2==0) return 0;//如果是偶数,表示不满足27 ...
阅读全文
摘要:没什么好说的……#includeint main(){ int n; while(scanf("%d",&n)){ if(n==-1) break; printf("I bet on Oregon Maple~\n"); } return 0;}View Code
阅读全文
摘要:题意是给出A个杯子,一开始都朝上,每次可以翻B个杯子,问最少需要翻转多少次可以让所有杯子都朝下。分类讨论:首先对于A%B==0一类情况,直接输出。对于A>=3B,让A减到[2B,3B)区间内,翻转次数累加上A/B-2。当A>=2B时,分奇偶讨论:A为奇数B为偶数显然无解;AB同奇偶时最多需要3次,A偶数B奇数最多需要4次。当A 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #define ll __int64 9 #define pi acos(-1.0)10 #define MAX 5000
阅读全文
摘要:思路:给一个数n,是否只有4个约数(包括1),也就是找3个大于1的约数。而任何一个数都可由质数表示,所以对于给定的数,只需要进行质因数分解。这里有2种情况:如果有3个一样的质因数,则满足条件;否则只需要2个不同的质因子。代码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #define ll __int64 9 #define pi acos(-1.0)10 #define MAX 500000111 using namespace std;12 ll n,e[5];13 in
阅读全文
摘要:博弈论水题!!!代码如下: 1 #include 2 #include 3 using namespace std; 4 int main(){ 5 int i,t,n,k,m; 6 while(cin>>n){ 7 m=0;t=0; 8 for(i=0;i>k;10 if(k>=2) t++;11 m^=k;12 }13 if((m==0&&t>=2)||(m!=0&&t==0)) cout<<"No"<<endl;14 else cout<<"Ye...
阅读全文
摘要:很简单的博弈论问题!!(注意全是1时是特殊情况)代码如下: 1 #include 2 #include 3 using namespace std; 4 int main(){ 5 int i,t,n,k,m; 6 bool flag; 7 scanf("%d",&t); 8 while(t--){ 9 scanf("%d",&n);10 flag=0;m=0;11 for(i=0;i>k;13 m^=k;14 if(k>1) flag=1;15 }1...
阅读全文
摘要:纯数论题,不解释!!!!代码如下: 1 #include 2 int main(){ 3 int i,j,t,n,k=0,m; 4 scanf("%d",&t); 5 while(t--){ 6 scanf("%d",&n); 7 printf("Case #%d:\n",++k); 8 m=n*(n-1); 9 for(i=1;i<=n;i++){10 for(j=1;j<n;j++)11 printf("%d ",(i-1)*(n-1)+j);12...
阅读全文
摘要:看懂题目,很容易想到容斥原理。刚开始我用的是二进制表示法实现容斥原理,但是一直超时。后来改为dfs就过了……代码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #define ll __int64 9 #define pi acos(-1.0)10 #define MAX 5000011 using namespace std;12 ll an[16],ans;13 int n;14 int get(ll n)15 {16 int t=0;17 while(n)...
阅读全文
摘要:这题用到了卡特兰数,详情见:http://www.cnblogs.com/jackge/archive/2013/05/19/3086519.html解体思路详见:http://blog.csdn.net/lvlu911/article/details/5425974代码如下:#include#include#include#include#include#include#include#define ll __int64#define pi acos(-1.0)#define MAX 50000using namespace std;int an[19]={1,1,2,5,14,42,132
阅读全文
摘要:例子:123以内0的个数:个位是0时:12*1;十位是0时:1*10;但是303的十位是0时的个数为2*10+4!代码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #define ll __int64 9 #define pi acos(-1.0)10 #define MAX 5000011 using namespace std;12 ll solve(ll n)13 {14 if(n>n>>m){32 if(n<0&&m<0)
阅读全文
摘要:思路:首先要建立坐标,具体作法见:http://www.cnblogs.com/xin-hua/p/3237096.html然后将得到2坐标之差x,y;如果x,y同号,则相加,否则去最大.(要取绝对值的)代码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #define ll __int64 9 #define pi acos(-1.0)10 #define MAX 5000011 using namespace std;12 struct dir13 {14 int ...
阅读全文
摘要:题目的意思很容易理解.就是找两个不同坐标的对应关系.下面的思路转自POJ的论坛首先,记由1到2的方向记为2,1到3的方向记为3……1到7的方向记为7,他们分别是:(0,1),(-1,1),(-1,0),(0,-1),(1,-1),(1,0);这些规律不仅对于1的周围六个方向有效,对于所有的点都是有效的。然后记1所在为圈1,2..7为圈1,8..19为圈2……,所以,很容易可以得到第n圈有蜂窝6n个(n>0),对于这个等差数列求和,S[1..n]=3n^2+3n,包括第0圈的1,则S[0..n]=3n^2+3n+1。读入数字x,解方程3n^2+3n+1=x,解出来n=[sqrt(12x-3
阅读全文
摘要:随机化算法+贪心!将3*k排序后分成3分,将第二第三份的和分别加起来,让和与500*k比较,都大于则输出,否则,随机生成2个数,在第二第三份中交换!代码如下:#include#include#include#includeusing namespace std;struct an{ int w,lab;}p[200];bool cmp(const an &a,const an &b){ return a.w>n; for(i=0;i>p[i].w; p[i].lab=i+1; } sort(p,p+3*n,cmp); sa=0;sb=0; ...
阅读全文
摘要:方法1:暴力法矩阵乘法+优化可以卡时间过的。方法2:随机化随机构造向量x[1..n],则有xAB=xC;这样可以将小运算至O(n^2).代码如下:#include#include#include#includeusing namespace std;int a[501][501],b[501][501],c[501][501],n,x[501];bool cal(){ int i,j,k; long long an[501],an2[501]; long long ans; long long sum=0; for(i=0;i>n; for(i=0;i<n;...
阅读全文
摘要:思路:要求最短时间从A到D,则走的路线一定是AB上的一段,CD上的一段,AB与CD之间的一段。那么可以先三分得到AB上的一个点,在由这个点三分CD!!代码如下:#include#include#include#include#include#include#include#define ll __int64#define pi acos(-1.0)using namespace std;double P,Q,R,ab,cd;struct point{ double x,y;}an[4],pp,qq;int n;double dis(point &a,point &b){ ret
阅读全文
摘要:思路:三分法求解凸函数的极值,三分法介绍在这:http://hi.baidu.com/czyuan_acm/item/81b21d1910ea729c99ce33db很容易就可以推出旋转后的坐标:x'=xcos(a)-ysin(a);y'=ycos(a)+xsin(a).cal(a)的意义就是在原来坐标上的点经过a弧度逆旋转后,正方形(边与坐标轴平行)最小边长要多长cal()在旋转的时候符合凸函数,所以三分求最值代码如下:#include#include#include#include#include#include#include#define ll __int64#defi
阅读全文
摘要:0/1分数规划问题,用二分解决!!代码如下:#include#include#include#include#include#include#define pi acos(-1.0)using namespace std;double a[1001],b[1001],an[1001];int main(){ int i,j,k,n; double l,r,sum,mid; while(cin>>n>>k){ if(n==0&&k==0) break; for(i=0;i>a[i]; for(i=0;i>b[i]; l=0...
阅读全文
摘要:这题主要是推导数学公式!!!将概率问题转化为圆心所在的面积!代码如下:#include#include#include#include#include#include#define pi acos(-1.0)using namespace std;int main(){ int i=0,k; double a1,a2,a3,a4,sum,r,m,n,t,c; cin>>k; while(k--){ cin>>m>>n>>t>>c; r=c/2.0; sum=m*n*t*t; a2=c*((t-c)*n+c)*(m-...
阅读全文
摘要:概率DP,递推式:dp[i][j]=sigma(dp[i-1][j]*p[j][k]*dp[i-1][k])再就是判断j和k是否相邻:if(((k>>(i-1))^1)==(j>>(i-1)))代码如下:#include#include#include#include#include#includeusing namespace std;double dp[129][129],p[129][129];int main(){ int i,j,k,ans,n; while(cin>>n){ if(n==-1) break; for(i=0;i>p[i][j
阅读全文
摘要:这个题有很多解法,不过还是觉得高斯消元比较好……以前用其他方法做的:#include#includeusing namespace std;int press[6][8];int puzzle[6][8];int main(){ int i,n; cin>>n; for(i=1;i>puzzle[j][k]; for(j=1;j1) { press[1][k+1]++; k++; press[1][k-1]=0; } ...
阅读全文
摘要:看题就知道要使用高斯消元求解!代码如下:#include#include#include#include#includeusing namespace std;int an[70][71],p,ans[70];char str[71];int pows(int a,int b){ int ans=1; while(b){ if(b&1) ans=(ans*a)%p; b>>=1; a=(a*a)%p; } return ans%p;}int gcd(int a,int b){ if(aan[row][i]) row=j; ...
阅读全文
摘要:由于数据量不大,所以这题有很多解法。我用的是高斯消元化为逆矩阵解决的……代码如下:#include#includeusing namespace std;int an[9][10]={{1,1,0,1,0,0,0,0,0,0},{1,1,1,0,1,0,0,0,0,0},{0,1,1,0,0,1,0,0,0,0},{1,0,0,1,1,0,1,0,0,0},{1,0,1,0,1,0,1,0,1,0},{0,0,1,0,1,1,0,0,1,0},{0,0,0,1,0,0,1,1,0,0},{0,0,0,0,1,0,1,1,1,0},{0,0,0,0,0,1,0,1,1,0}},ans[9];in
阅读全文
摘要:看题就知道要用polya,但是当时没做出来,还是不是很熟悉polya!!!总共有24种置换:1. 不做任何旋转 K ^ (54 + 12 + 8)2. 绕相对面中心的轴转1) 90度 K ^ (15 + 3 + 2) * 31) 180度 K ^ (28 + 6 + 4) * 31) 270度 K ^ (15 + 3 + 2) * 33. 绕相对棱中心的轴转1) 180度K ^ (27 + 7 + 4) * 64. 绕相对顶点的轴转1) 120度K ^ (18 + 4 + 4) * 41) 240度K ^ (18 + 4 + 4) * 4代码如下:#includeint pows(int a,
阅读全文
摘要:直接枚举就行了#include#include#include#include#include#include#include#define ll __int64#define pi acos(-1.0)#define SIZE 1024using namespace std;const int mod =1000000007;vectorp;int main(){ ll i,j,t; ll n,sum,num; while(cin>>n){ p.clear(); i=j=1; sum=0; num=(ll)sqrt(n...
阅读全文
摘要:读完题目就知道要使用容斥原理做!下面用的是二进制实现的容斥原理,详见:http://www.cnblogs.com/xin-hua/p/3213050.html代码如下:#include#include#include#include#include#include#include#define ll __int64#define pi acos(-1.0)#define MAX 50000using namespace std;double an[22];double solve(int n){ int i,j; double ans=0.0; for(i=1;i>n){ ...
阅读全文
摘要:有5个数列,将第一,二列合并去重得到s1,再将第三,四列合并去重得到s2,这样就剩下3列了。然后将s1,s2排序,枚举第5列,每次用x指向s1的头,y指向s2的尾,当取出的3个和恰好为0则退出;大于0时y--;否则x++!代码如下:#include#include#include#include#include#include#include#define ll __int64#define pi acos(-1.0)#define MAX 50000using namespace std;ll a[202],b[202],c[40002],d[40002];vectors1,s2;int m
阅读全文
摘要:将每一个数分解质因数,得到每个质因数出现的次数(和质数本身没有关系),然后就要用到容斥原理了,也就是将每个质数出现的次数放到n个容器中去,这里要注意下1的情况也就是某个容器里面没有放数。这样结果=总的方案数-有一个容器没放数+有2个容器没有放数……将m个数放入n个容器的方法数有C(n+m-1,n-1)!代码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #define ll __int64 9 #define pi acos(-1.0)10 #define SIZE 10241
阅读全文

浙公网安备 33010602011771号