2020牛客暑期多校训练营(第七场)J.Pointer Analysis

2020牛客暑期多校训练营(第七场)J.Pointer Analysis

题目链接

题目描述

Pointer analysis, which aims to figure out which objects accessible via a specific pointer variable in a program during the execution, is one of the fundamental parts of static program analysis. Now we want you to perform the context-insensitive pointer analysis on the test data.

A program contains 26 objects denoted by lowercase letters and each object has 26 member variables (a.k.a. fields, which are pointers that may point to some objects) denoted by lowercase letters as well. Meanwhile, there are 26 global pointers in the programs designated by uppercase letters.

There are four kinds of statements in a program. We use [Variable] to represent the name of a pointer, [Field] to represent the name of a member variable, and [Object] to represent an object.

FormatExampleDescription
Allocation[Variable] = [Object]A = xpointer A can point to object x (i.e., x is accessible via A)
Assignment[Variable] = [Variable]A = Bpointer A can point to every object accessible via B
Store[Variable].[Field] = [Variable]A.f = Bfor every object o accessible via A, the member variable f of o can point to every object accesible via B
Load[Variable] = [Variable].[Field]A = B.ffor every object o accessible via B, A can point to every object accessible via the member variable f of o

The context-insensitive pointer analysis assumes that statements of the program will be executed in any order for a sufficient number of times. For example, in the following two programs, both A and B can point to the object x and object o. The reason for that is, in the real world, the exact execution order and execution times of statements are difficult to predict.

First ProgramSecond Program
A = o A = x B = AB = A A = x A = o

Now you are asked to perform a context-insensitive pointer analysis on a given program consists of N statements, and for each pointer, output the objects it can point to.

输入描述:

The first line of the input contains one integer N ( 1 ≤ N ≤ 200 ) N (1 \le N \le 200) N(1N200), representing the number of statements in the program. There is exactly one space before and after the equal sign ‘=’.

Each of the following N lines contains one statement.

输出描述:

The output should contains 26 lines.

In the i-th line, output the name of the i-th pointer (which is the i-th uppercase letter) followed by a colon ‘:’ and a space, and then list the objects accessible via this pointer in alphabetical order.

示例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:

示例2

输入

4
A = o
B.f = A
C = B.f
C = g

输出

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

示例3

输入

3
A = o
B = A
A = x

输出

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

模拟,至于简不简单,仁者见仁智者见智了😂
我们队比赛时一直纠结两个地方,一个是题意,一个是顺序,然后就没有然后了/(ㄒoㄒ)/~~
我赛后看了别人的过题代码,很多都直接用 O ( N 2 ) O(N^2) O(N2) 的方法,这样直接解决了顺序问题,因为每一行代码重复执行并不影响答案的正确性~
下面就是题意的问题,我发现不用懂题意,直接按题目意思来就行:
我们不难发现答案是排序的,且去重的,很容易想到数据结构 s e t set set
所以就按题目意思来,用 a n s [ 30 ] ans[30] ans[30] 存储答案,题目说有 26 26 26 个对象,每个对象有 26 26 26 个指针,那么可以用 o b j e c t [ 30 ] [ 30 ] object[30][30] object[30][30] 来记录每个对象的每个指针指向的对象,这里就是题意不太明确的地方,在这题里,一个指针可以指代多个对象,那么就按表格里的四个要求来模拟(不懂题意也行)就行了,AC代码如下:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
string s1[205],s2[205];
char a,b,c;
set<char>ans[30],object[30][30];
int main(){
   int n;
   cin>>n;
   for(int i=0;i<n;i++) cin>>s1[i]>>c>>s2[i];
   for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            a=s1[j][0]-'A',b=s2[j][0]-'A';
            if(s1[j].size()==1&&s2[j].size()==1){
                if(islower(s2[j][0])) ans[a].insert(s2[j][0]);
                else{
                    for(auto k:ans[b]) if(ans[a].find(k)==ans[a].end()) ans[a].insert(k);
                }
            }else if(s1[j].size()==3){
                c=s1[j][2]-'a';
                for(auto k:ans[a]){
                    for(auto l:ans[b])
                        object[k-'a'][c].insert(l);
                }
            }else{
                c=s2[j][2]-'a';
                for(auto k:ans[b]){
                    for(auto l:object[k-'a'][c])
                        ans[a].insert(l);
                }
            }
        }
    }
    for(int i=0;i<26;i++){
        cout<<char(i+'A')<<": ";
        for(auto j:ans[i]) cout<<j;
        cout<<"\n";
    }
}
©️2020 CSDN 皮肤主题: 程序猿惹谁了 设计师:上身试试 返回首页