2014北邮新生归来赛解题报告a-c
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">完全没状态的新生归来赛,虐的很惨</span>
A Hard Game
And it's now going to be a hard game. N piles
of coins are put down on the ground, where each piles contains exactly M coins.
Alice and Bob is coming to take coins again, and Alice starts first. The two players alternately choose a pile and take some number of coins(NOT zero, indeed) from the one he/she chooses. Your task is to judge who will win the game if both of them take the
best strategy.
输入格式
The first line is the number of test cases T(1≤T≤1000).
Each test case consists of only two integers N and M(1≤N,M≤109).
输出格式
Output 'Alice' if she wins, otherwise output 'Bob'.
输入样例
1
1 2
输出样例
Alice
一听名字就知道是最简单的签到题,一道很简单的简化nim,异或看为0不为0就行
这道题局势(2)时因为只有可能Alice拿走2个或者Alice1个Bob1个,胜者又是Alice,所以是拿到最后一颗的人胜,所以面对(0)的人就必定输了
nim博弈的共性:存在一个或多个状态起点和确定的状态转移路径,必败状态时只有一条或多条通向终局的必败路径,此时就算输,下一步只有必败状态(留给对手)就算必胜,必败态势中留给对手的总是非必败态势,若设必败态势是T,必胜态势S,那么必然有
1 T不能转移到T,只能转移到S,
2 S必然可以转移到T,
对于任意一组局面,(a1,a2,...,an)都存在2种可能 1 这组局面是T状态 2 这组局面是S状态
如何确定是否T态呢?
对于这组局面,若ak是最大值,那么当初始状态异或之和不为0时
使ak成为a1^a2^a3^a4...an(除去ak的异或结果)时,(ak-=(a1^a2^....an))
下一步的局势异或之和必定为0,此时不管对手怎么操作,异或之和都必定不为0,于是己方可以操作使其异或为0,
使异或为0的状态对应T态(0异或为0),异或不为0的状态对应S态,这个时候恰满足S态T态的状态转移.
而当初始异或为0时,ak就是a1^a2...an就没有办法改变了,也就是必败状态.
所以S态是异或之和不为0,T是异或之和为0
这个思路有点像数学归纳法
或者可以用sg函数,先来看单独一堆sg函数sg(x)=mex(sg(y)|y是x的后继节点).mex表示取到的非负整数集合没有出现后面那个集合中的最小数,我觉得sg函数就是用于路径压缩的并查集,那么sg(x)=0就是必败态,但这个游戏中存在的单独堆必不为必败态,
对于sg(x)=k.意味着它可以到达0-k-1任意某个状态,明显对这个游戏sg(x)=x,由Bouton’s
Theorem,只要每个堆的异或之和为0就是必败态了
这道题简化在于每堆数目都相等,那么就奇数异或之和肯定不为0,也就是n%2!=0必胜,
/*
USER_ID: test#xuesu
PROBLEM: 396
SUBMISSION_TIME: 2014-07-12 13:35:16
*/
#include <iostream> using namespace std; int main()
{
int t;
cin >>t;
while(t--){
int n,m;
cin>>n>>m;
if(n%2==0)cout <<"Bob"<<endl;
else cout << "Alice" << endl;
}
return 0;
}
B. Prime Judge 2014新生归来赛
KB
题目描述
众所周知,如果一个正整数只能被1和自身整除,那么该数被称为素数。题目的任务很简单,就是判定一个数是否是一个素数。 只不过可能数的形式与正整数有一些不同,数的形式为a+bi,其中a、b为整数,且ii被定义为-1。如果a+bi能被分解为(a1+b1i)(a2+b2i)的形式,那么该数不是素数;否则,该数是素数。其中a1 、b1、 a2 、b2均为整数,且1,-1,0,i,-i不能作为被分解的因子。 注意,1,-1,0,i,-i均不为素数。
输入格式
输入包括若干组数据,每行包含2个数a、b,表示一个形如a+bi的数。a,b小于10000。
输出格式
对应于输入每行,如果输入的数为素数,则输出“YES”,否则输出“NO”。(不包括引号)
输入样例
-10 2
3 0
输出样例
NO
YES
这道题,好吧....连暴力都只是在最后半小时想到的....只是在思考:这会有什么性质,结果什么都没思考出来,到了最后半小时时间太急,果然没打出来,撞墙,撞墙
经验教训:没有使用计算机的思维,没有算法的思维,交给计算机跑就可以了.....即使算法复杂度有点高,只要能过就成,思路太过于零散了,没有整块的思路一开始想到了a*a+b*b=(a1*a1+b1*b1)(a2*a2+b2*b2)但是以为那是必然条件没有管它,但其实因为若n是平方和,那么一定能分解为唯一一对a,b>0使得a*a+b*b=n,也即实际上是充要条件,之后的问题是:漏看了a,,b<10000.不知道为什么就只认为范围是100,汗.,,,,,,,总之范围是10000时穷举不能,
查了查百度知道:
平方数的形式具有下列形式之一:16m,16m+1, 16m+4,16m+9
第一个数就先穷举,10*8复杂度,第二个数经过检查后二分,2a*a+2b*b-(a+b)*(a+b)是否为完全平方数,
不过怎么样还是不过,查看丁神代码(话说原来有小伙伴在csdn)发现原来是a*a+b*b=0或1 的时候没有处理,折腾了2小时....
思路:1 首先两重循环找小于sqrt(sq=(a*a+b*b))的平方和(分解因数)
2 然后不断除直到另一个因数为奇数,此时一定是一个奇数平方和,一个偶数平方和,%16余数一定是1,9,5,13之一,用这个条件筛一筛
3 使用2a*a+2b*b-(a+b)*(a+b)是否为完全平方数确认
#include<iostream>
#include <cmath>
using namespace std;
long long sqsum[20001];
int findequalorlessindex(int s,int e,long long aim){
int mid=(s+e)/2;
if(mid==s)return s;
if(sqsum[mid]>aim)return findequalorlessindex(s,mid,aim);
return findequalorlessindex(mid,e,aim);
}//二分搜索,设a>=b,则a*a+b*b<=(a+b)*(a+b)<=2a*a+2b*b
int main(){
for(int i=0;i<20001;i++){
sqsum[i]=i*i;
}
int a,b;
while(cin>>a>>b){
long long sq=a*a+b*b;
bool fl=true;
int sqroot2=sqrt(sq);
for(int i=0;i<10000;i++){
for(int j=i;j<10000;j++){
if(sqsum[i]+sqsum[j]>sqroot2)break;
if(sqsum[i]+sqsum[j]==0||sqsum[i]+sqsum[j]==1)continue;
if(sq%(sqsum[i]+sqsum[j])==0){
long long divisor=sq/(sqsum[i]+sqsum[j]);
while(divisor%2==0)divisor/=2;
int r=divisor%4;
if(r!=1)continue;
int indexofd=findequalorlessindex(1,20001,divisor);
int indexof2d=findequalorlessindex(1,20001,2*divisor);
for(int i=indexofd;i<=indexof2d;i++){
long long sqsumasubb=2*divisor-sqsum[i];
if(sqsumasubb<0)continue;
long long sqroot=sqrt(sqsumasubb);
if(sqroot*sqroot==sqsumasubb){
fl=false;
break;
}
}
}
}
if(!fl||sqsum[i]>=sqroot2)break;
}
if(sq==0||sq==1)fl=false;
if(fl)cout<<"YES\n";
else cout <<"NO\n";
}
return 0;
}
下面贴某神代码:
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <iostream>
#include <vector>
#include <algorithm> using namespace std; int main()
{
long long a,b;
while (~scanf("%lld%lld",&a,&b))
{
long long sp=a*a+b*b;
bool judge=false;
for (int i=2;i<=sqrt(sp);i++)
{
if (sp%i!=0) continue;
int j=sp/i;
while (i%2==0) i/=2;
while (j%2==0) j/=2;
if (i%4==1&&j%4==1)
{
judge=true;
break;
}
}
if (sp==1||sp==0) judge=true;
if (judge) printf("NO\n");
else printf("YES\n"); }
}
证明4n+1型素数一定能分解为两平方数之和:
4n+1为奇数,所以如果为两平方数之和,则其一为偶数平方,另一为奇数平方。设x=2m,4m^2<=4n,即m^2<=n时,有4n-m^2+1为一个奇数的平方。设y=2p+1,y^2=4p^2+4p+1,x^2+y^2=4m^2+4p^2+4p+1=4(m^2+p^2+p)+1,∴,当n=m^2+p^2+p时,成立。
c:
398. Freeway
KB
题目描述
Krishna is a country with n cities, there are n-1 freeways between cities.If we don't consider direction of freeway, there is a unique path between every two cities. But unfortunately, some of freeways are directed.
Now,there is a war between Krishna and Trots. In order to save valuable time, Moor, the High Command of Krishna, decided to transform freeways by change there's direction. So that soldiers in the central camp can reach any other cities from the central camp
by freeways. The cost of transform one freeway is the same as the lenth of the freeway. In order to reduce expenditure, Moor has to choose a city as central camp to minimize the cost. But Moor is too busy, you should help him to find the position of central
camp.
输入格式
There are multiply test case, and end of EOF Firstly give a integer
n(0<n<100000).The following n-1 lines give 4 integers: t,u,v,w, whitch means that there are a freeway of length w between u and v(0=<w<=5000,0<u,v<100000). If t = 1, the freeway is directed, if t = 0, the freeway is undirected.
输出格式
Print two integers, the first one stands for the city whitch has central camp, the second one stands for the minimal cost to transform the freeway. If there exist many cities satify the condition, you should put
central camp in the city with smallest id.
输入样例
5
1 1 2 3
1 2 3 1
0 2 4 5
1 5 4 4
输出样例
5 3
晕,原来这道题不可能有环,因为是n座城市,n-1条路而且还连通,人生啊,撞墙,没看清题意...我说用什么bellman啊...
这题真坑,城市的号不是连通的也有可能,不是从1开始的也有可能,这是说明人生有无穷多种可能吗?吗?
思路: dp,先得到从第一个城市出发的总路程(每条路径只需算一遍,如果是没有这个方向的就加0).然后从第一个城市出发到第二个城市(加2->1减1->2),得出所有点的最大可覆盖路程,用应当达到的总路程-最大可覆盖路程即可,时间复杂度n
#include <iostream>
#include <cstring>
using namespace std;
int first[100022];//没看到10^6,wa一次
int next[200024];
int to[200024];
int cost[200024];
bool vis[100022];
int n;
int maxn,minn;
int ans;
void dfs(int i ){
int p=first[i];
while(p!=-1){
if(!vis[to[p]]){
ans+=cost[p];
vis[to[p]]=true;
dfs(to[p]);
}
p=next[p];
}
}
int dp[100022];
int maxcost;
int maxi;
void dfs2(int i){
int p=first[i];
if(dp[i]>maxcost){
maxcost=dp[i];
maxi=i;
}
while(p!=-1){
if(!vis[to[p]]){
dp[to[p]]=dp[i]-cost[p];
if(p%2)dp[to[p]]+=cost[p-1];
else dp[to[p]]+=cost[p+1];
if(dp[to[p]]>maxcost){//神坑,这要是在后面从minn-maxn统计一遍就wa了,wa一次
maxcost=dp[to[p]];
maxi=to[p];
}
vis[to[p]]=true;
dfs2(to[p]);
}
p=next[p];
}
}
int topdfs(){
memset(vis,0,sizeof(vis));
ans=0;
vis[minn]=true;
dfs(minn);//从随便哪个点出发先求得一个dp基值
dp[minn]=ans;
memset(vis,0,sizeof(vis));
vis[minn]=true;
maxi=minn;
maxcost=ans;
dfs2(minn);//从这个点出发遍历,得到所有可覆盖的总路径长度
return maxi;
}
int main(){
ios::sync_with_stdio(false);
while(cin>>n){
memset(first,-1,sizeof(first));
int d,u,v,w;
int costsum=0;
maxn=0;
minn=0x3ffffff;
for(int i=0;i<n-1;i++){
cin>>d>>u>>v>>w;
if(u>maxn)maxn=u;//神坑,不一定在1开始,n截止
if(v>maxn)maxn=v;
if(u<minn)minn=u;
if(v<minn)minn=v;
costsum+=w;
to[2*i]=v;
cost[2*i]=w;
next[2*i]=first[u];
first[u]=2*i;
if(d){
to[2*i+1]=u;
cost[2*i+1]=0;
next[2*i+1]=first[v];
first[v]=2*i+1;
}
else {
to[2*i+1]=u;
cost[2*i+1]=w;
next[2*i+1]=first[v];
first[v]=2*i+1;
}
}
topdfs();
cout<<maxi<<" "<<costsum-maxcost<<"\n";
}
return 0;
}
2014北邮新生归来赛解题报告a-c的更多相关文章
- 2014北邮新生归来赛解题报告d-e
D: 399. Who Is Joyful 时间限制 3000 ms 内存限制 65536 KB 题目描述 There are several little buddies standing in a ...
- 北邮新生排位赛1解题报告d-e
话说cdsn要是前面插入源代码又什么都不放就会出现奇怪的源代码?不知道是哪个网页的 407. BLOCKS 时间限制 1000 ms 内存限制 65536 KB 题目描述 给定一个N∗M的矩阵,求问里 ...
- 北邮新生排位赛1解题报告a-c
<div class="page-header" style="padding-bottom: 9px; margin: 20px 0px 30px; border ...
- 北邮新生排位赛2解题报告a-c
A. 丁神去谷歌 2014新生暑假个人排位赛02 时间限制 1000 ms 内存限制 65536 KB 题目描述 丁神要去Google上班了,去之前丁神想再做一道水题,但时间不多了,所以他希望题目做起 ...
- 北邮新生排位赛2解题报告d-e
<> 427. 学姐逗学弟 时间限制 3000 ms 内存限制 131072 KB 题目描述 学弟们来了之后,学姐每天都非常高兴的和学弟一起玩耍.这一天,学姐想出了这样一个游戏,她画了一棵 ...
- 【百度之星2014~初赛(第二轮)解题报告】Chess
声明 笔者近期意外的发现 笔者的个人站点http://tiankonguse.com/ 的非常多文章被其他站点转载.可是转载时未声明文章来源或參考自 http://tiankonguse.com/ 站 ...
- 【百度之星2014~初赛(第二轮)解题报告】JZP Set
声明 笔者近期意外的发现 笔者的个人站点http://tiankonguse.com/ 的非常多文章被其他站点转载,可是转载时未声明文章来源或參考自 http://tiankonguse.com/ 站 ...
- ZROIDay4-比赛解题报告
ZROIDay4-比赛解题报告 扯闲话 感觉这个出题人的题做起来全都没感觉啊,今天又凉了,T1完全不知道什么意思,T2只会暴力,T3现在还不懂什么意思,真的太菜了 A 题意半天没搞懂爆零GG了,讲了一 ...
- ZROIDay3-比赛解题报告
ZROIDay3-比赛解题报告 瞎扯 从今天开始考试有点不在状态,可能是因为不太适应题目的原因,T1已经接近了思想但是没有想到状态转移,T2思考方向错误,T3不会打LCT,还是太菜了 A 考场上想到要 ...
随机推荐
- Win7_Wifi热点
1. 怎样在Win7系统建立并开启Wifi热点 http://jingyan.baidu.com/article/48a42057a03cf7a9242504d0.html 2.
- OpenWrt网络结构
原文链接:http://www.freezhongzi.info/?p=104 OpenWrt网络结构 OpenWrt的网络配置很丰富,在我看来几乎可以完成任何网络结构.下图为一个支持OpenWrt的 ...
- Android中Activity、Service和线程之间的通信
Activity.Service和线程应该是Android编程中最常见的几种类了,几乎大多数应用程序都会涉及到这几个类的编程,自然而然的,也就会涉及到三者之间的相互通信,本文就试图简单地介绍一下这三者 ...
- GoF--命令设计模式
定义 将来自客户端的请求传入一个对象,从而使你可用不同的请求对客户进行参数化.用于“行为请求者”与“行为实现者”解耦,可实现二者之间的松耦合,以便适应变化.分离变化与不变的因素. 角色 Command ...
- angular 模板 小例子
参考网站:https://docs.angularjs.org/tutorial/step_09 先看下目录结构 新建个空文件夹, 输入命令: express --view ejs cnpm inst ...
- WebViewJavascriptBridge-Obj-C和JavaScript互通消息的桥梁
转载至:http://www.cocoachina.com/ios/20150629/12248.html 译者:@coderyi9 本文翻译自Marcus Westin的开源框架WebViewJav ...
- 关于JVM的类型和模式
原文出处: 摆渡者 引言 曾几何时,我也敲打过无数次这样的命令: 然而之前的我都只关心过版本号,也就是第一行的内容.今天,我们就来看看第3行输出的内容:JVM的类型和工作模式. 其实说Server和C ...
- JavaWeb基础:Servlet
Servlet 基本概念 Servlet是Sun公司提出的一种用于开发动态Web资源的技术规范: Servlet是一个Java接口, 用户想要开发自定义的Servlet可以通过以下步骤: 编写实现Se ...
- Linux基础: 挂载镜像文件(Mount & ISO)
ISO/Ghost 镜像文件概念(裸机安装,无光驱安装,跨平台安装) ISO是镜像文件:所谓镜像文件其实和ZIP压缩包类似,它将特定的一系列文件按照一定的格式制作成单一的文件,以方便用户下载和使用,例 ...
- 关于位域如何节省内存(C++)
位域: 最先使用在c语言中后来C++继承了这一优良的特点. 举个栗子: int --> 4字节 2^32位 ,如果我们只需要其表达一个0~16的数字, 使用一个int就显得稍稍 ...