zoukankan      html  css  js  c++  java
  • 【GMOJ6826】隔膜

    题目

    题目链接:https://gmoj.net/senior/#main/show/6826

    思路

    如果无法找到任意一个 (k imes k) 的正方形,显然后手胜。
    如果所有 (k imes k) 的正方形的交不为空集,那么先手将交集中任意一个点点掉就胜利,所以先手胜。
    否则必然存在至少两个不互相相交的正方形,考虑到当只剩下最后两个不互交的正方形时,先手必败,所以假设除了这两个正方形外一共有 (cnt) 个格子,两人轮流选一个改变,如果 (cnt) 是奇数则先手胜,否则后手胜。
    又因为总共的空格子数量等于 (2k^2+cnt),与 (cnt) 奇偶性相同,所以可以直接判断总共空格子数量。
    至于如何判断是否有至少两个正方形不交,直接将所有正方形找出来,分别按照横坐标和纵坐标排序两次,拿横坐标来说,如果排序后第一个正方形上底的横坐标比最后一个正方形下底的横坐标小,那么显然这两个正方形不交。
    时间复杂度 (O(n^2log n^2))。完全可以做到 (O(n^2)) 但是懒。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N=1010;
    int n,m,sum,cnt,a[N][N],b[N][N];
    
    struct node
    {
    	int a,b,c,d;
    }c[N*N];
    
    bool cmp1(node x,node y)
    {
    	return x.a<y.a;
    }
    
    bool cmp2(node x,node y)
    {
    	return x.b<y.b;
    }
    
    int main()
    {
    	freopen("lcyrcx.in","r",stdin);
    	freopen("lcyrcx.out","w",stdout);
    	scanf("%d%d",&n,&m);
    	for (int i=1;i<=n;i++)
    		for (int j=1;j<=n;j++)
    		{
    			scanf("%1d",&a[i][j]);
    			b[i][j]=b[i-1][j]+b[i][j-1]-b[i-1][j-1]+a[i][j];
    			if (!a[i][j]) sum++;
    		}
    	for (int i=m;i<=n;i++)
    		for (int j=m;j<=n;j++)
    			if (b[i][j]-b[i-m][j]-b[i][j-m]+b[i-m][j-m]==0)
    				c[++cnt]=(node){i-m+1,j-m+1,i,j};
    	if (!cnt) return printf("yc"),0;
    	sort(c+1,c+1+cnt,cmp1);
    	if (c[1].c<c[cnt].a)
    		return (sum&1) ? printf("rx"),0 : printf("yc"),0;
    	sort(c+1,c+1+cnt,cmp2);
    	if (c[1].d<c[cnt].b)
    		return (sum&1) ? printf("rx"),0 : printf("yc"),0;
    	printf("rx");
    	return 0;
    }
    
  • 相关阅读:
    c#基础语法(第二节课后作业/笔记)
    C#第四节课
    Hello, cnblog!
    64位的系统可以让IIS在32位的环境下运行asp.net程序(转)
    Web.Config中设置Session问题,导致无法向会话状态服务器发出会话状态请求
    远程测试asp.net web service 配置
    jQuery不使用$方法
    导入数据到SQL SERVER 2005方法
    图片与Base64相互转换,c#与java通用
    一道递归算法题,一道冒泡算法题
  • 原文地址:https://www.cnblogs.com/stoorz/p/13846889.html
Copyright © 2011-2022 走看看