2020牛客暑期多校训练营Pointer Analysis(模拟,指针,BFS迭代)

这篇博客主要解析了一道涉及指针分析的题目,通过BFS迭代方法进行求解。首先解释了题目的输入和输出描述,然后通过样例分析解题思路。在理解题意的基础上,博主指出可以将大写和小写字母直接相连,并通过逆向迭代计算每个指针的可能指向。最后,虽然遇到了不能使用`auto`关键字的困扰,但博主还是提供了完整的AC代码实现。
摘要由CSDN通过智能技术生成

Pointer Analysis

题目描述

在这里插入图片描述

输入描述:

在这里插入图片描述

输出描述:

在这里插入图片描述

示例1

输入

5
B.f = A
C = B.f
C = x
A = o
B = o

输出

A: o
B: o
C: ox
D:
E:
F:
G:
H:
I:
J:
K:
L:
M:
N:
O:
P:
Q:
R:
S:
T:
U:
V:
W:
X:
Y:
Z:

样例23见原题,过长不放。

题目大意

这题的重点就是理解题意。
有一些指针和对象,指针有的是全局指针,用大写字母表示,有的是成员指针,用大写字母.小写表示。有的是对象,用小写字母表示。
现在你可以对给出的 n n n个操作进行任意顺序的进行和重复使用,求对于每个指针,有多少种指向的可能。

分析

这是道有指针内容的题,还不会的点这里
首先我们来考虑样例一是怎么出答案的。
首先我们是把一个大写一个小写的能直接连的先连了。
C → x A → o B → o C\to x\qquad A\to o\qquad B\to o CxAoBo
然后把之后的也连上。
C → x B → A → o C → B → o C\to x\qquad B\to A\to o\qquad C\to B\to o CxBAoCBo
所以 A A A可以指向 o o o B B B可以指向 o o o C C C可以指向 o o o x x x
看管可以自己用这样的策略去算算样例23.

然后再考虑我们是怎么统计每个指针的可能指向的。
在这里插入图片描述
观察上面这个图,就是根据指针画的指向图。其实每次我们从小写字母开始,然后逆向迭代,如果是大写字母,那么加入其答案中,最后去重就可以了,本质上就是个指针的模拟。
下面是官方给的伪代码:
在这里插入图片描述
接下来就是根据伪代码写的ACcode

代码

注:以下内容可能引起不适,慎入慎入。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
bool AA(char c){return c>='A'&&c<='Z';}//判断大写
bool aa(char c){return c>='a'&&c<='z';}//判断小写
int CC(char c){return c-'A';}//大写转数字
int cc(char c){return c-'a';}//小写转数字
struct node{
	char a[5],b[5];
}op[210];
char rbs[5];
set<int> st,v[30],pt[30][30];
int main()
{
	 int t;
	 scanf("%d",&t);
	 for(int i=1;i<=t;i++){
	 	scanf("%s%s%s",op[i].a,rbs,op[i].b);
	 	if(AA(op[i].a[0])&&aa(op[i].b[0])&&strlen(op[i].a)==1){
	 		st.insert(cc(op[i].b[0]));
	 		v[CC(op[i].a[0])].insert(cc(op[i].b[0]));
	 		//先把一个大写一个小写的放进去
	 	}
	 }
	 while(!st.empty()){
	 	while(!st.empty()){
	 		int now=*st.begin();
	 		st.erase(now);
	 		for(int i=1;i<=t;i++){
	 			if(AA(op[i].a[0])&&AA(op[i].b[0])&&strlen(op[i].a)==1&&strlen(op[i].b)==1){
	 				int siz=v[CC(op[i].a[0])].size();
	 				set<int>::iterator it=v[CC(op[i].b[0])].begin();
	 				for(it;it!=v[CC(op[i].b[0])].end();it++)//禁止auto
	 					v[CC(op[i].a[0])].insert(*it);
	 				if(v[CC(op[i].a[0])].size()!=siz)
	 					st.insert(op[i].a[0]);
	 			}
	 		}
	 	}
	 	for(int i=1;i<=t;i++){
	 		if(strlen(op[i].a)==3&&AA(op[i].b[0])&&strlen(op[i].b)==1){
	 			set<int>::iterator j=v[CC(op[i].a[0])].begin();
	 			for(j;j!=v[CC(op[i].a[0])].end();j++){
	 				set<int>::iterator k=v[CC(op[i].b[0])].begin();
	 				for(k;k!=v[CC(op[i].b[0])].end();k++){
	 					pt[*j][cc(op[i].a[2])].insert(*k);
	 				}
	 			}
	 		}
	 	}
	 	for(int i=1;i<=t;i++){
	 		if(strlen(op[i].b)==3&&AA(op[i].a[0])&&strlen(op[i].a)==1){
	 			set<int>::iterator j=v[CC(op[i].b[0])].begin();
	 			for(j;j!=v[CC(op[i].b[0])].end();j++){
	 				int siz=v[CC(op[i].a[0])].size();
	 				set<int>::iterator k=pt[*j][cc(op[i].b[2])].begin();
	 				for(k;k!=pt[*j][cc(op[i].b[2])].end();k++)
	 					v[CC(op[i].a[0])].insert(*k);
	 				if(v[CC(op[i].a[0])].size()!=siz)
	 					st.insert(CC(op[i].a[0]));
	 			}
	 		}
	 	}
	 }
	 for(int i=0;i<26;i++){
	 	printf("%c: ",'A'+i);
	 	set<int>::iterator j=v[i].begin();
	 	for(j;j!=v[i].end();j++)
	 		printf("%c",*j+'a');
	 	puts("");
	 }
}

END

难受,不能用auto不能用auto不能用auto不能用auto不能用auto!!!

迭代器打死我了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值