阴阳龙 第31次CCF-CSP计算机软件能力认证

时间:2025-04-22 08:46:43

25分暴力代码:
储存为邻接矩阵 进行广度遍历 寻找到最近的距离和结点

然后去进行坐标变换操作

问题就是:邻接矩阵太大了存不下 而且只需要判断当前坐标是否满足条件 不需要都遍历 ,理论上维护坐标位置 每次根据数学表达式决定是否更新就可以。

#include <bits/stdc++.h>
using namespace std;
int n, m, p, q;

vector<vector<int>> graph(1003, vector<int>(1003, 0));
int dx[8] = {1,1,0,-1,-1,-1,0,1};
int dy[8] = { 0,1,1,1,0,-1,-1,-1 };
map<int, pair<int, int>> worker;
struct node {
	pair<int, int> p;
	int di;
	node() {}
	node(int u, int v, int k, int di) { p.first = u; p.second = v; k = k; di = di; }
};
//获得V1集合和对应的坐标
pair <map<int, vector<node>>, set<int>> get_V1(int u, int v) {
	map<int, vector<node>> V1_map;
	set<int> V1_set;
	//遍历整张图 从阴阳龙结点开始八个方向为一个循环 循环次数是个问题
	int count = max(max(m - v, v - 1),max(u - 1, n - u));
	//循环count次 count代表距离
	for (int i = 1; i <= count; i++) {
		//寻找八个方向的员工
		for (int j = 0; j < 8; j++) {
			int now_x = u + dx[j];
			int now_y = v + dy[j];
			if (graph[now_x][now_y] == 1) {
				V1_map[i].push_back(node(u,v,i,j));
				V1_set.insert(i);
			}		
		}
	}
	return { V1_map,V1_set };
}

//改变位置
void change(vector<node> nearest, int t,int k) {
	for (node worker : nearest) {
		int now_x = worker.p.first;
		int now_y = worker.p.second;
		int di = worker.di;
		int k = k;
		int new_x = now_x + k * dx[(di + t) % 8];
		int new_y = now_y + k * dy[(di + t) % 8];
		graph[now_x][now_y] = 0;
		graph[new_x][new_y] = 1;
	}
}

//work函数
void work(int u, int v, int t) {
	pair<map<int, vector<node>>,set<int>> V1=get_V1(u,v);
	if (V1.second.empty())
		return;
	else {
		int k = V1.first.begin()->first;
		vector<node> nearest=V1.first[k];
		change(nearest, t,k);
	}

}

//获得坐标结果
int get_result() {
	int result;
	for (int i = 1; i <= p; i++) {
		if (i == 1)
			result = i * worker[i].first + worker[i].second;
		else
			result = result ^ (i * worker[i].first + worker[i].second);
	}
	return result;
}
int main() {
	// n*m:代表图的大小 (1,1) (n,m)
	// p:员工个数 1-p
	// q:阴阳龙现身次数
	cin >> n >> m >> p >> q;
	for (int i = 1; i <= p; i++) {
		int x, y;
		cin >> x >> y;
		graph[x][y] = 1;
		worker[i] = { x,y };
	}
	while (q--) {
		int u, v, t;
		cin >> u >> v >> t;// 阴阳龙坐标:(u,v) 强度:t
		work(u, v, t);
		cout << get_result();
	}
}




满分代码:
 

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
 
const int dx[8] = {1, 1, 0, -1, -1, -1, 0, 1};
const int dy[8] = {0, 1, 1, 1, 0, -1, -1, -1};
 
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n, m, p, q;
    cin >> n >> m >> p >> q;
    vector<array<int, 2>> pos(p);
    unordered_map<int, set<array<int, 2>>> row, col, ld, rd;
    auto insert = [&](int id){
        int x = pos[id][0], y = pos[id][1];
        row[x].insert({y, id});
        col[y].insert({x, id});
        ld[x + y].insert({y, id});
        rd[x - y].insert({y, id});
    };
    auto remove = [&](int id){
        int x = pos[id][0], y = pos[id][1];
        row[x].erase({y, id});
        col[y].erase({x, id});
        ld[x + y].erase({y, id});
        rd[x - y].erase({y, id});
    };
    for(int i = 0; i < p; ++ i){
        cin >> pos[i][0] >> pos[i][1];
        insert(i);
    }
    for(int i = 0; i < q; ++ i){
        int u, v, t;
        cin >> u >> v >> t;
        vector<array<int, 3>> candidate;
 
        auto search = [&](const set<array<int, 2>>& people, int d, int dirr, int dirl){
            auto pos = people.lower_bound(array<int, 2>{d, p});
            if (pos != people.end()){
                candidate.push_back({(*pos)[0] - d, (*pos)[1], dirr});
            }
            if (pos != people.begin()){
                pos = prev(pos);
                if ((*pos)[0] == d && pos != people.begin())
                    pos = prev(pos);
 
                if ((*pos)[0] != d){
                    candidate.push_back({d - (*pos)[0], (*pos)[1], dirl});
                }
            }
        };
 
        search(row[u], v, 2, 6);
        search(col[v], u, 0, 4);
        search(ld[u + v], v, 3, 7);
        search(rd[u - v], v, 1, 5);
 
        if (candidate.empty())
            continue;
        sort(candidate.begin(), candidate.end(), [&](const array<int, 3>& a, const array<int, 3>& b){
            return a[0] < b[0];
        });
        int mindis = min({u - 1, n - u, v - 1, m - v});
        if (candidate[0][0] > mindis)
            continue;
        mindis = candidate[0][0];
        for(int i = 0; i < candidate.size(); ++ i){
            if (candidate[i][0] != mindis)
                break;
            int dis = candidate[i][0];
            int id = candidate[i][1];
            remove(id);
            int dir = (candidate[i][2] + t) % 8;
            pos[id][0] = u + dis * dx[dir];
            pos[id][1] = v + dis * dy[dir];
            insert(id);
        }
    }
    LL ans = 0;
    for(int i = 0; i < p; ++ i){
        ans ^= (1ll * (i + 1) * pos[i][0] + pos[i][1]);
    }
    cout << ans << '\n';
    return 0;
}