Testing Round #16 (Unrated) 测试人数4695
[codeforces 1351C] Skier 区分出不同位置+连成图+找重边/map+pair的写法/set+pair的写法
总目录详见https://blog.csdn.net/mrcrack/article/details/103564004
在线测评地址https://codeforces.com/contest/1351/problem/C
1.区分出不同位置+连成图+找重边
Problem | Lang | Verdict | Time | Memory |
---|---|---|---|---|
C - Skier | GNU C++17 | Accepted | 62 ms | 9800 KB |
提供一个难点数据
Input:
1
NESW
Output:
20
思路:
'N':-100010;'S':+100010;'W':-1;'E':+1;很好的将四个方向的移动区分出来。
点确定之后,进行构图,找重边。
AC代码如下
#include <cstdio>
#include <cstring>
#include <map>
#define LL long long
#define maxn 100010
using namespace std;
char s[maxn];
int head[maxn],tot;
struct node{
int to,next;
}e[maxn<<1];//无向图
void add_edge(int u,int v){//邻接表
tot++,e[tot].to=v,e[tot].next=head[u],head[u]=tot;
}
int main(){
int t,len,i;
scanf("%d",&t);
while(t--){
int sum=0,cnt=0,v,flag;
map<LL,int> mp;//映射,将LL数据,映射成int数据,方便之后的空间开辟。
scanf("%s",s+1);
len=strlen(s+1);
LL x=0,pre;
pre=x,mp[pre]=++cnt;
tot=0;//初始化
for(i=1;i<=len;i++)head[i]=0;//初始化
for(i=1;i<=len;i++){//'N':-100010;'S':+100010;'W':-1;'E':+1;很好的将四个方向的移动区分出来。
if(s[i]=='N')x-=100010;
else if(s[i]=='S')x+=100010;
else if(s[i]=='W')x-=1;
else if(s[i]=='E')x+=1;
if(!mp[x])mp[x]=++cnt;//映射点
flag=0;
for(int b=head[mp[pre]];b;b=e[b].next){
v=e[b].to;
if(v==mp[x]){flag=1;break;}//找到对应的边
}
if(flag)sum+=1;
else add_edge(mp[pre],mp[x]),add_edge(mp[x],mp[pre]),sum+=5;//构图,前一个点pre,后一个点x
pre=x;//当前点x,变成下一条边的起始点pre。
}
printf("%d\n",sum);
}
return 0;
}
2.map+pair的写法
Problem | Lang | Verdict | Time | Memory |
---|---|---|---|---|
C - Skier | GNU C++17 | Accepted | 46 ms | 8600 KB |
比较操作数
//两个pair类型数据可以直接使用 ==, !=, <, <=, >, >= 比较大小,比较规则先以first的大小作为标准
//只有当first相等时才去判别second的大小
AC代码如下
#include <cstdio>
#include <algorithm>
#include <map>
#include <cstring>
#define maxn 100010
using namespace std;
char s[maxn];
int main(){
int t,x1,y1,x2,y2,len,ans,i;
scanf("%d",&t);
while(t--){
map<pair<pair<int,int>,pair<int,int> >,int> mp;
pair<int,int> p,q;
scanf("%s",s+1);
len=strlen(s+1);
x1=0,y1=0,ans=0;
for(i=1;i<=len;i++){
x2=x1,y2=y1;
if(s[i]=='N')y2--;
else if(s[i]=='S')y2++;
else if(s[i]=='W')x2--;
else if(s[i]=='E')x2++;
p=make_pair(x1,y1),q=make_pair(x2,y2);
if(p>q)swap(p,q);
if(mp[make_pair(p,q)])ans++;
else ans+=5;
mp[make_pair(p,q)]++;
x1=x2,y1=y2;
}
printf("%d\n",ans);
}
return 0;
}
3.set+pair的写法
Problem | Lang | Verdict | Time | Memory |
---|---|---|---|---|
C - Skier | GNU C++17 | Accepted | 46 ms | 7800 KB |
比较操作数
//两个pair类型数据可以直接使用 ==, !=, <, <=, >, >= 比较大小,比较规则先以first的大小作为标准
//只有当first相等时才去判别second的大小
AC代码如下
#include <cstdio>
#include <algorithm>
#include <set>
#include <cstring>
#define maxn 100010
using namespace std;
char s[maxn];
int main(){
int t,x1,y1,x2,y2,len,ans,i;
scanf("%d",&t);
while(t--){
set<pair<pair<int,int>,pair<int,int> > > st;
pair<int,int> p,q;
scanf("%s",s+1);
len=strlen(s+1);
x1=0,y1=0,ans=0;
for(i=1;i<=len;i++){
x2=x1,y2=y1;
if(s[i]=='N')y2--;
else if(s[i]=='S')y2++;
else if(s[i]=='W')x2--;
else if(s[i]=='E')x2++;
p=make_pair(x1,y1),q=make_pair(x2,y2);
if(p>q)swap(p,q);
if(st.count(make_pair(p,q)))ans++;
else ans+=5;
st.insert(make_pair(p,q));
x1=x2,y1=y2;
}
printf("%d\n",ans);
}
return 0;
}
类似的题目有
[codeforces 1296C] Yet Another Walking Robot 三重排序+全网唯一的代码/STL中map+pair/类hash算法