从零单排9

一会儿物理实验考试选课~貌似网站又瘫痪了。。。

昨天网上稍微看了看博弈,然后今天上午做了一点博弈。。SG函数完全是套模版。。再难一点的博弈就不会了。。

仍然停留在找规律的弱菜水平。。。另外看了一点欧拉回路 。。。原来这东西一般会用到并查集。。(一阵窃喜。。),欧拉图的判定条件还没有搞会。。。


下午和晚上再看看,然后打一下的内容差不多快结束了吧。。

然后就开始复习unix...下周考试了撒。。。

9. 博弈论
a) 博弈问题与SG函数的定义
b) 多个博弈问题SG值的合并
10. 图论:
a) 图的邻接矩阵与邻接表两种常见存储方式
b) 欧拉路的判定
c) 单最短路bellman-ford算法dijkstra算法。
d) 最小生成树的kruskal算法与prim算法。
11. 学会使用C语言进行网络编程与多线程编程
12. 高等数学
13. 线性代数
a) 明确线性代数的重要性,首先是课本必须学好
b) 编写一个Matrix类,进行矩阵的各种操作,并求编写程序解线性方程组。
c) 推荐做一两道“矩阵运算”分类下的题目。


题解:

hdu 1846:http://acm.hdu.edu.cn/showproblem.php?pid=1846

/*
额。。还有比这更简单的博弈么。。。
*/
#include<iostream>
using namespace std;
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		int n,m;
		cin>>n>>m;
		if(n%(m+1)==0)
		{
			cout<<"second"<<endl;
		}
		else
		{
			cout<<"first"<<endl;
		}
	}
	system("pause");
	return 0;
}

hdu 1847: http://acm.hdu.edu.cn/showproblem.php?pid=1847

/*
变种bash博弈 
请允许我采用枚举法找规律。
*/
#include<iostream>
using namespace std;
int main()
{
	int n;
	while(cin>>n)
	{
		if(n%3==0)	
			cout<<"Cici"<<endl;
		else
			cout<<"Kiki"<<endl;
	}
	system("pause");
	return 0;
}

hdu 1907: http://acm.hdu.edu.cn/showproblem.php?pid=1907

/*
Nim博弈裸题。。
什么充裕态孤单态。。目前还没看懂。。
纯粹套的模版。。
*/
#include<iostream>
using namespace std;
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		int n;
		cin>>n;
		int num=0;
		int ans=0;
		while(n--)
		{
			int a;
			cin>>a;
			if(a>1)
			{
				num++;
			}
			ans^=a;
		}
		if(num)
		{
			if(ans==0)
			{
				cout<<"Brother"<<endl;
			}
			else
			{
				cout<<"John"<<endl;
			}
		}
		else
		{
			if(ans==0)
			{
				cout<<"John"<<endl;
			}
			else
			{
				cout<<"Brother"<<endl;
			}
		}
	}
	system("pause");
	return 0;
}

hdu 2509: http://acm.hdu.edu.cn/showproblem.php?pid=2509

/*
Nim博弈裸题。。
什么充裕态孤单态。。目前还没看懂。。
纯粹套的模版。。
*/
#include<iostream>
using namespace std;
int main()
{
	int T;
	int n;
	while(cin>>n)
	{
		int num=0;
		int ans=0;
		while(n--)
		{
			int a;
			cin>>a;
			if(a>1)
			{
				num++;
			}
			ans^=a;
		}
		if(num)
		{
			if(ans==0)
			{
				cout<<"No"<<endl;
			}
			else
			{
				cout<<"Yes"<<endl;
			}
		}
		else
		{
			if(ans==0)
			{
				cout<<"Yes"<<endl;
			}
			else
			{
				cout<<"No"<<endl;
			}
		}
	}
	system("pause");
	return 0;
}

hdu 1517: http://acm.hdu.edu.cn/showproblem.php?pid=1517

/*
感觉和bash博弈差不多,只不过由加法变成了乘法,
木有想到。。。 
题解来自:http://qianmacao.blog.163.com/blog/static/203397180201223174133470/
犀利啊。。
 
①、如果输入是2~9,因为Stan是先手,所以Stan必胜。

②、如果输入是10~18(9*2),因为Ollie是后手,不管第一次Stan乘的是多少,Stan肯定在2~9之间,如果Stan乘以2,那么Ollie就乘以9,那么Ollie乘以大于1的数都能超过10~18中的任何一个数,Ollie必胜。

③、如果输入的是19~162(9*2*9),那么这个范围Stan必胜。

④、如果输入是163~324(2*9*2*9),这个是Ollie的必胜范围。

…………

可以发现必胜态是对称的。

如果“我方”首先给出了一个在N不断除18后的得到不足18的数M,“我方”就可以胜利,然而双方都很聪明,所以这样胜负就决定与N了,如果N不断除18后的得到不足18的数M,如果1<M<=9则先手胜利,即Stan wins.如果9<M<=18则后手胜利。
*/
#include <iostream>
using namespace std;
int main()
{
    double n;
    while(cin >> n)
    {
        while(n > 18)
           n /= 18;
        if(n <= 9)
            cout << "Stan wins." << endl;
        else
            cout << "Ollie wins." << endl;
    }
    return 0;
}

hdu 1536: http://acm.hdu.edu.cn/showproblem.php?pid=1536

/*
裸SG函数
套模版。。。
*/
#include <iostream>
#include <algorithm>
using namespace std;
const int M = 10005;
int sg[M];
int set[M];
int check[M];
int k,n,m;
int mmax;
int mex(int v)
{
    if(sg[v] != -1)
		return sg[v];
    bool vis[101] = {0};
    for(int i = 0; i < k; i++)
    {
        if(v-set[i] < 0)
			break;
        sg[v-set[i]] = mex(v-set[i]);
        vis[sg[v-set[i]]] = true;
    }
    for(int i = 0; ; i++)
    	if(!vis[i])
		{
			sg[v] = i;
		 	break;
		}
	return sg[v];
}
int main()
{
    while(cin>>k&&k!=0)
    {
        mmax = 0;
        memset(set,0,sizeof(set));
        for(int j = 0; j < k; j++)
        {
            cin>>set[j];
        }
        sort(set,set+k);
        memset(sg,-1,sizeof(sg));
        sg[0] = 0;
        cin>>m;
        while(m--)
        {
            cin>>n;
            int ans = 0;
            for(int i = 0; i < n; i++)
            {
                int x;
                cin>>x;
                if(sg[x] == -1)
					sg[x] = mex(x);
                ans ^= sg[x];
            }
            if(!ans)
				cout<<"L";
            else 
				cout<<"W";
        }
        cout<<endl;
    }
    return 0;
}

hdu 1878: http://acm.hdu.edu.cn/showproblem.php?pid=1878

/*
欧拉回路判定
1.回路(用并查集判断(擅长啊哈哈))
2.欧拉图(不含奇数度结点)
*/
#include<iostream>
using namespace std;
int father[1005];
int map[1005];
int num;
int find(int x)
{
	if(x==father[x])
	{
		return x;
	}
	else
	{
		return find(father[x]);
	}
}
void Union(int x,int y)
{
	x=find(x);
	y=find(y);
	if(x!=y)
	{
		father[x]=y;
		num++;
	}
}
void init()
{
	for(int i=1;i<=1000;i++)
	{
		father[i]=i;
	}
}
int main()
{
	int n,m;
	while(cin>>n&&n!=0)
	{
		init();
		memset(map,0,sizeof(map));
		num=1;
		cin>>m;
		while(m--)
		{
			int x,y;
			cin>>x>>y;
			map[x]++;
			map[y]++;
			Union(x,y);
		}
		if(num==n)
		{
			int i;
			for(i=1;i<=n;i++)
			{
				if(map[i]%2==1)
				{
					cout<<"0"<<endl;
					break;
				}
			}
			if(i>n)
			{
				cout<<"1"<<endl;
			}
		}
		else
		{
			cout<<"0"<<endl;
		}
	}
	system("pause");
	return 0;
}

hdu 3018: http://acm.hdu.edu.cn/showproblem.php?pid=3018

/*
欧拉回路+并查集
一笔画问题
数组开小了wa了好几次
这个题其实就个一笔划问题,如果是个欧拉回路一笔就可以完成,如果是个其它连通集,
要根据这个集合的奇度数而定,笔划数=奇度数/2,用并查集来判断有多少个连通集,
通过判断度数是奇偶性来确定是否为欧拉回路;总之笔划数 = 奇度数%2 + 欧拉回路数;
*/
#include<iostream>
using namespace std;
int n,m;
int father[200005];
int map[200005];
int cnt[200005];
int a[200005];
int b[200005];
int find(int x)
{
	if(x==father[x])
	{
		return x;
	}
	else
	{
		return find(father[x]);
	}
}
void Union(int x,int y)
{
	x=find(x);
	y=find(y);
	if(x!=y)
	{
		father[x]=y;
		cnt[y]+=cnt[x];
	}
}
void init()
{
	memset(map,0,sizeof(map));
	memset(cnt,0,sizeof(cnt));
	for(int i=1;i<=n;i++)
	{
		father[i]=i;
	}
}
int main()
{
	while(cin>>n>>m)
	{
		init();
		for(int i=1;i<=m;i++)
		{
			cin>>a[i]>>b[i];
			map[a[i]]++;
			map[b[i]]++;
		}
		for(int i=1;i<=n;i++)
		{
			if(map[i]%2==1)
			{
				cnt[i]=1;
			}
		}
		for(int i=1;i<=m;i++)
		{
			Union(a[i],b[i]);
		}
		int sum=0;
		for(int i=1;i<=n;i++)
		{
			if(map[i]&&father[i]==i)
			{
				if(cnt[i]==0)
				{
					sum++;
				}
				else
				{
					sum+=cnt[i]/2;
				}
			}
		}
		cout<<sum<<endl;
	}
	system("pause");
	return 0;
}

hdu 1116: http://acm.hdu.edu.cn/showproblem.php?pid=1116


/*
再好好看看欧拉图。。。
知道用并查集但不知道要干嘛。。。
搜的题解: 
思路:并查集&&欧拉通路
1)所有的点联通
2)欧拉回路中所有点的入度和出度一样。
3)欧拉通路中起点的入度 - 出度 = 1,终点的 初度 - 入度 = 1, 
其他的所有点入度 = 出度;
*/
#include <iostream>
using namespace std;
#define M 30
int father[M],vis[M],in[M],out[M],ans[M];
char ch[1005];
int find(int x)
{
	if(x==father[x])
	{
		return x;
	}
	else
	{
		return find(father[x]);
	}
}
void Union(int x,int y)
{
	x=find(x);
	y=find(y);
	if(x!=y)
	{
		father[x]=y;
	}
}
void init()
{
	memset(vis,0,sizeof(vis));
    memset(in,0,sizeof(in));
    memset(out,0,sizeof(out));
    for(int i=0;i<26;i++)
    	father[i]=i;
}	
int main()
{
    int T,n,a,b;
    cin>>T;
    while(T--)
    {
        cin>>n;
		init();        
        for(int i=0;i<n;i++)
        {
            cin>>ch;
            a=ch[0]-'a';
            b=ch[strlen(ch)-1]-'a';
            Union(a,b);
            out[a]++;
            in[b]++;
            vis[a]=1;
            vis[b]=1;
        }
        for(int i=0;i<26;i++)
    	    father[i]=find(i);
        int cnt=0;
        for(int i=0;i<26;i++)
    	    if(vis[i]&&father[i]==i)
       	    	cnt++;
        if(cnt>1)
        {
            cout<<"The door cannot be opened."<<endl;
            continue;
        }
        int j=0;
        for(int i=0;i<26;i++)
        	if(vis[i]&&out[i]!=in[i])
            	ans[j++]=i;
        if(j==0)
        {
            cout<<"Ordering is possible."<<endl;
            continue;
        }
        if(j==2&&( (out[ans[0]]-in[ans[0]]==1&&in[ans[j-1]]-out[ans[j-1]]==1)
                 ||(out[ans[j-1]]-in[ans[j-1]]==1&&in[ans[0]]-out[ans[0]]==1) ))
        {
            cout<<"Ordering is possible."<<endl;
            continue;
        }
        cout<<"The door cannot be opened."<<endl;
    }
}

旁边这人可真烦尼玛。。。抖腿鼻涕一时爽。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值