CTU Open Contest 2019 J.Beer Vision

CTU Open Contest 2019 J.Beer Vision

We are given a (drunken) image of stars as seen by a drunken man lying on his back on thegrass in the vicinity of a closed pub late in the evening. His image is a blend of one original(sober) image, and a copy of the same image shifted by some fifixed (X, Y ) nonzero vector. Onlythe resulting blended image is perceived by the drunkard. Neither the original sober image northe shift vector are available to him and to us, unfortunately.

An act of humanity would be to restore his perceived image to the version seen by his soberfellow citizens.

Given an image, write a program which calculates how many distinct (X, Y ) vectors exist suchthat the drunken image can be created by merging some original sober image with its copyshifted by the vector.

Note that if the images of two difffferent stars — one in the original image and the other in itsshifted copy — overlap in the blended image, then the drunken image, which is also the inputof the program, contains only one entry for this position.

Input Specifification

The fifirst line of input contains an integer N (0 < N ≤ 1000), the number of stars in theblended (drunken) image. Next, there are N lines, each with two space-separated integers Xi, Yi ( 1000 ≤ Xi, Yi ≤ 1000) describing the position of a star. All stars are regarded to be pointswith no dimensions.

Output Specifification

Print the number of distinct vectors with non-zero length which can be applied to an unknownsober picture to produce the input drunken image. The unknown image might be difffferent indifffferent cases.

样例输入1

5
0 0
1 1
2 2
2 0
3 1

样例输出1

2

样例输入2

3
0 0
0 1
1 0

样例输出2

0

这道题题意比较难理解,其实就是找符合条件的向量(正反皆可),使得图上所有点经向量变换后都存在,我们只需要枚举每一个向量即可,不难发现将图旋转只需以其中任一点为基点,该点与其余点构成的向量即为所有情况,所以复杂度最多2e3。注意正反向量都存在的情况,避免重复计算,AC代码如下:

#include 
using namespace std;
typedef long long ll;

map<pair<int,int>,int>m,M;//m记录点,M记录向量
int n,vx,vy,x[1005],y[1005],ans=0;
int check(){//检查点变换后是否还在图上
    for(int i=1;i<n;i++)
    {
        if(m[make_pair(x[i]+vx,y[i]+vy)]==0 && m[make_pair(x[i]-vx,y[i]-vy)]==0) return 0;
    }
    return 1;
}

int main(){
    cin>>n;
    for(int i=0;i<n;i++){
        scanf("%d%d",&x[i],&y[i]);
        m[make_pair(x[i],y[i])]=1;
    }
    for(int i=1;i<n;i++){
        vx=x[i]-x[0],vy=y[i]-y[0];
        if(!M[make_pair(vx,vy)] && check()) ans++;
        M[make_pair(vx,vy)]=1;
        if(!M[make_pair(-vx,-vy)]){//判断相反向量
            vx=-vx,vy=-vy;
            M[make_pair(vx,vy)]=1;
            if(check()) ans++;
        }
    }
    cout<<ans;
    return 0;
}

你可能感兴趣的:(map,pair,ICPC)