8.25 欢乐emmm赛

三道题

A现代艺术
时间限制 : - MS   空间限制 : 165536 KB 
评测说明 : 1s
问题描述

何老板是一个现代派的艺术家。他在一块由n*n的方格构成的画布上作画。一开始,所有格子里的数字都是0。
何老板作画的方式很独特,他先后给N^2个子矩阵涂上了颜色,每次都是从1到N^2这些数字中选一个给对应矩阵全部填上该数字。比如:
第1步,他选数字2填在了一个子矩阵上。如下图:

2 2 2 0 
2 2 2 0 
2 2 2 0 
0 0 0 0
第2步,他用数字7填在了一个子矩阵上:
2 2 2 0 
2 7 7 7 
2 7 7 7 
0 0 0 0
第3步,他用数字3填在了一个子矩阵上:
2 2 3 0 
2 7 3 7 
2 7 7 7 
0 0 0 0
以此填涂下去,直到1到N^2中每个数字都被用过了一次(每个数字只能被使用一次)。
现在何老板已经完成了他的艺术创作,你得到了最后的图形。
何老板问你,根据这幅作品,你能够推断出第一步填涂的数字可能是哪些呢?输出第一步填涂可能的数字的个数。
输入格式

第一行,一个整数N(1<=N<=1000)
接下来一个N*N的数字矩阵,表示画作最终的样子。

输出格式

一个整数,表示第一步填涂可能的数字个数。

样例输入

4
2 2 3 0 
2 7 3 7 
2 7 7 7 
0 0 0 0

样例输出

14

提示

样例解释,数字2是最先被填涂的。数字3显然在数字7后才填涂,数字7显然在数字2后被填涂。
因为看不到其他数字,所以,这些数字有可能出现在数字2之前,后来被覆盖了。

第一题  以为是个一眼题  但是忽略了很多情况

开始以为只需要讨论数字的个数(太单纯  :)

来说正解  二维查分讨论重叠部分:

通过对角线的数值+二维查分添加(不用查分就是暴力  会超时)

#include<stdio.h> 
#include<bits/stdc++.h>
#include<cctype>
using namespace std;
int n,f[1005][1005],a,g,ff,mark[1000005],summ[1005][1005],markx[1000005],marky[1000005],markxx[1000005],markyy[1000005],sum[1005][1005],k[1000005],ans;
char buf[1<<20],*p1,*p2;  
#define GC (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?0:*p1++)  
template<class T> inline void read(T &n){  
    char ch=GC;T w=1,x=0;  
    while(!isdigit(ch)){if(ch=='-') w=-1;ch=GC;}  
    while(isdigit(ch)){x=(x<<3)+(x<<1)+(ch^48);ch=GC;}  
    n=x*w;  
}
int main()
{
mark[0]=1;
read(n);
for(int i=1;i<=n*n;i++)markx[i]=marky[i]=1e9;
for(int i=1;i<=n;i++)
   for(int j=1;j<=n;j++)
{
read(a);
f[i][j]=a;
if(mark[f[i][j]]==0)
{
mark[f[i][j]]=1;
g++;
}
markx[f[i][j]]=min(i,markx[f[i][j]]);
marky[f[i][j]]=min(j,marky[f[i][j]]);
markxx[f[i][j]]=max(i,markxx[f[i][j]]);
markyy[f[i][j]]=max(j,markyy[f[i][j]]);//更新一下对角线 
}
if(g==1)cout<<n*n-1;
else{ 
   for(int i=1;i<=n*n;i++)
   {
    if(mark[i]==1)
    {
    sum[markx[i]][marky[i]]+=1;
    sum[markxx[i]+1][marky[i]]-=1;
    sum[markx[i]][markyy[i]+1]-=1;
    sum[markxx[i]+1][markyy[i]+1]+=1;
    }
   }

for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
summ[i][j]=sum[i][j]+summ[i-1][j]+summ[i][j-1]-summ[i-1][j-1];
if(summ[i][j]>1)
{
if(k[f[i][j]]==0)
{
k[f[i][j]]=1;
ff++;          
}
}
}
ans=n*n-ff;
cout<<ans;
}
}

猜你喜欢

转载自www.cnblogs.com/cocacolalala/p/11408395.html