2020 Multi-University Training Contest 7 07,09,10

AC:09,10

hdu6850 1007 Game 

很容易想到,如果先手到达最长点对之一,则必败。(后手可以走最长点对的另一点,使得先手无处可走)

对于一个游戏,把他转化为无向图。

先找出当前图中最长的边d。

然后把边长为d的所有边连接的点都删去(这些点称为必败点,到达即必败),然后这些点设为一层(称为必败层,即先手到这一层必败)

然后得到新的无向图。重复上述操作。

直到图只剩一个点,或者为空,最后的一个点设为一层。

显然这是一个分层图,只能由底层走向高层,且先跨层的人必败。

而且每层的距离都相同,说明每层最多只能移动一次。

即:若一个点x在某一层,他可以选在在这一层一定,则下一步的人必须跨层。

由此得到必胜策略:

对于点x,若其所在层点数不为1,则必胜,否则必败(必须跨层)

#include 
using namespace std;
typedef long long ll;
typedef long double ld;
#define ls (o<<1)
#define rs (o<<1|1)
#define pb push_back
const double PI= acos(-1.0);
const int N = 2000+7;
/*
int head[M],cnt=1;
void init(){cnt=1,memset(head,0,sizeof(head));}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}
*/
struct node{
	ll x,y;
}p[N];
struct EDGE{
	int u,v;ll dis;
//	bool operator < (const EDGE &r)const{
//		return dis>T;
	while(T--)
	{
		int n;
		scanf("%d",&n);
		for(int i=1;i<=n;i++)
			scanf("%lld%lld",&p[i].x,&p[i].y),vs[i]=0;
		int sz=0;
		for(int i=1;i<=n;i++)
			for(int j=1;j=1;i--)
		{
			int u=e[i].u,v=e[i].v;
			if(vs[u]||vs[v])continue;
			int j=i;
			vectorvv;
			while(j&&e[j].dis==e[i].dis)
			{
				if(vs[e[j].u]||vs[e[j].v])
				{
					j--;
					continue;
				}
				vv.pb(j);
				j--;
			}
			for(auto x:vv)
				vs[e[x].u]=vs[e[x].v]=1;
			i=j+1;
		}
		if(vs[1])puts("YES");
		else puts("NO");
	}
	return 0;
}

1009Increasing and Decreasing

思维水题

1010Jogging

显然若走到(i,i)则会无限游荡。则回到起点的概率为0.

若无法走,则必定留在原地。

现在问题是多个格子求留在起点的概率。

考虑上图,起点s,只在三个格子里游荡。若走无限步,则起点对结果不影响。

只考虑每个点由会由哪些情况到达即可:

对于点s:s停留会到达s,点1会到达s,共2种

对于点1:1停留在1,点2,s会到达1,共3种

对于点2:2停留在2,点1会到达2,共2种

则停留在点x的概率是总情况除到达点x的情况即可。

证明我也不会,但感性很容理解

而且题目给了样例,很容易猜出来

#include 
using namespace std;
typedef long long ll;
#define ls (o<<1)
#define rs (o<<1|1)
#define pb push_back
const double PI= acos(-1.0);
const int M = 1e5+7;
/*
int head[M],cnt=1;
void init(){cnt=1,memset(head,0,sizeof(head));}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}
*/
ll gcd(ll a,ll b)
{
    if(b==0)return a;
    return gcd(b,a%b);
}
bool flag=false;
int sm=0;
map,int>mp;
void dfs(ll x,ll y)
{
    //cout<<"--  "<1)
            {
            //    cout<<"=-=-==-           "<>T;
    while(T--)
    {
        ll x,y;
        scanf("%lld%lld",&x,&y);
        int fz=0;
        sm=0;flag=false;mp.clear();
        for(int i=-1;i<=1;i++)
            for(int j=-1;j<=1;j++)
                if(gcd(x+i,y+j)>1)fz++;
        dfs(x,y);
        if(flag)
        {
            puts("0/1");
            continue;
        }
        int c=gcd(fz,sm);
        printf("%d/%d\n",fz/c,sm/c);
    }
    return 0;
}
/*
3
18 16
18 6
18 8
*/

 

你可能感兴趣的:(2020多校hdu)