SPOJ 20848 IGAME
来源:互联网 发布:怎样编程游戏 编辑:程序博客网 时间:2024/06/06 04:39
Description
两个人玩游戏,初始给一个整数n,两人轮流操作,每次可以选择n的一位在保证该位非负的情况下减去任意值,谁先把n减到0谁赢,问在双方足够机智的情况下[A,B]中有多少值作为初始值可以使得先手必胜,有多少值作为初始值可以使后手必胜
Input
第一行一整数T表示用例组数,每组用例输入两整数A和B表示查询区间(1<=T<=1e4,1=A<=B<=1e18)
Output
Sample Input
2
1 10
101 110
Sample Output
10 0
8 2
Solution
经典取石子问题,问题变成求[1,n]中有多少数的各位异或和不是0,简单数位dp,dp[pos][state]表示当前在第pos位,前pos-1位的异或和是state的方案数
Code
#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#include<cmath>#include<vector>#include<queue>#include<map>#include<set>#include<ctime>using namespace std;typedef long long ll;#define INF 0x3f3f3f3fll dp[22][22],A,B;int T,a[22];ll dfs(int pos,int state,int fp){ if(pos==0) { if(state)return 1; return 0; } if(!fp&&dp[pos][state]!=-1)return dp[pos][state]; ll ans=0; int fpmax=fp?a[pos]:9; for(int i=0;i<=fpmax;i++)ans+=dfs(pos-1,state^i,fp&&i==fpmax); if(!fp)dp[pos][state]=ans; return ans;}ll Solve(ll n){ int res=0; while(n) { a[++res]=n%10; n/=10; } return dfs(res,0,1);}int main(){ memset(dp,-1,sizeof(dp)); scanf("%d",&T); while(T--) { scanf("%lld%lld",&A,&B); ll ans=Solve(B)-Solve(A-1); printf("%lld %lld\n",ans,B-A+1-ans); } return 0;}
0 0
- SPOJ 20848 IGAME
- SPOJ IGAME(Interesting Game-博弈+数位dp)
- IGAME
- [SPOJ IGAME Interesting Game]Nim 博弈+数位DP
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- scp上传下载
- SAX解析XML文档
- 接口限流算法总结
- POJ 1007 DNA Sorting
- java相似三角形
- SPOJ 20848 IGAME
- Elasticsearch script score plug 教程
- FFmpeg图解:avformat_alloc_output_context2
- OkHttp的使用
- mysql limit查询优化方法(offset偏移量)
- Reinforcement Learning学习总结
- 中国成为关键驱动:解读Forrester云计算研究报告(1)
- JDK和Tomcat环境搭配
- 蓝桥杯JAVB语言B组_循环节长度