题解:P8142 [ICPC 2020 WF] Which Planet is This?!
纯最小表示法做法,应该是尽可能做的最简洁的。
题意:给你两个地图,有
首先,题目的坐标是小数,最多
直接展示我的处理代码,该函数读入一个浮点数,并返回它的
int get(){
string s;
cin>>s;
int sgn=1,res=0,dot=0,cnt=4;
for(char i:s){
if(i=='-')sgn=-1;
if(i=='.')dot=1;
if('0'<=i&&i<='9'){
if(dot)cnt--;
res=res*10+(i-'0');
}
}
res=sgn*res*pow(10,cnt);
return res;
}
然后,由于合法的判定是存在合法差值
以上只是一个初步思路,因为
3
1 50
2 100
3 150
1 66
2 127
3 148
就能理解了吧。注意到全局加
总结以下,合法的判定是:
- 按
y 排序后,存在一种循环同构方案使得它们x 一一对应,y 的差分也一一对应。
随机凭做题直觉就感觉感觉到这个条件也是充分的。不理解的看代码吧:
#include<bits/stdc++.h>
using namespace std;
int n,del1,del2;
pair<int,int> p[400040],q[400040];
int get(){
string s;
cin>>s;
int sgn=1,res=0,dot=0,cnt=4;
for(char i:s){
if(i=='-')sgn=-1;
if(i=='.')dot=1;
if('0'<=i&&i<='9'){
if(dot)cnt--;
res=res*10+(i-'0');
}
}
res=sgn*res*pow(10,cnt);
return res;
}
int main(){
cin.tie(0)->sync_with_stdio(0);
cout.tie(0);
cin>>n;
for(int i=0;i<n;i++){int a=get(),b=get();p[i]={b,a};}
for(int i=0;i<n;i++){int a=get(),b=get();q[i]={b,a};}
sort(p,p+n);
sort(q,q+n);
p[n]={p[0].first+3600000,0};
for(int i=0;i<n;i++){
p[i].first=p[i+1].first-p[i].first;
}
q[n]={q[0].first+3600000,0};
for(int i=0;i<n;i++){
q[i].first=q[i+1].first-q[i].first;
}
int i=0,j=1,k=0;
while(i<n&&j<n&&k<n){
if(p[(i+k)%n]==p[(j+k)%n])k++;
else if(p[(i+k)%n]<p[(j+k)%n])j=j+k+1,k=0;
else i=i+k+1,k=0;
if(i==j)i++;
}
del1=min(i,j);
i=0,j=1,k=0;
while(i<n&&j<n&&k<n){
if(q[(i+k)%n]==q[(j+k)%n])k++;
else if(q[(i+k)%n]<q[(j+k)%n])j=j+k+1,k=0;
else i=i+k+1,k=0;
if(i==j)i++;
}
del2=min(i,j);
for(int i=0;i<n;i++){
if(p[(i+del1)%n]!=q[(i+del2)%n]){
cout<<"Different";
return 0;
}
}
cout<<"Same";
return 0;
}