选择题+编程题 官网有:GESP官网
编程题 1:交流问题
知识点: 宽搜, 深搜, 二分图染色; 并查集:拆点法
思路1
深搜染色, 直接上代码
源代码
#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;
const int N = 1e5+10;
vector<int> g[N];
int h[N], ans1, ans2, A, B;
void dfs(int i, int col){
if(!h[i]){
h[i] = col;
if(col==1) A++;
else B++;
for(int v:g[i])
dfs(v, 3-col);
}
}
int main() {
int n, m;
scanf("%d %d", &n, &m);
for(int i=1;i<=m;++i){
int u, v;
scanf("%d %d", &u, &v);
g[u].push_back(v);
g[v].push_back(u);
}
for(int i=1;i<=n;++i)
if(!h[i]){
A = B = 0;
dfs(i, 1);
ans1 += min(A, B);
ans2 += max(A, B);
}
printf("%d %d", ans1, ans2);
}
/**************************************************************
Problem: 2718
User: Teacher0029 [陈老师]
Language: C++
Result: 正确
Time:176 ms
Memory:11080 kb
****************************************************************/
思路2
每个点拆成两个点, 例如 1点 拆成 1与1’, 2点 拆成 2与2’…
并查集连边的时候, 如果1与2之间存在一条边, 那么 1与2’, 2与1’ 两对点并在一起…
最终每个连通块是同一个学校的…以后在解释详细…
编程题 2:俄罗斯方块
知识点: 大模拟, STL, 字符串哈希
思路1
字符串hash: 对二维图形编码, 排序+去重.
双hash也可以
自然溢出hash都可以
void gethash(){
normalize();
for(int i=0;i<v.size();++i){
hash=hash*100003+v[i].x*503+v[i].y;
hash%=10000000019;
hash2=hash2*100019+v[i].x;
hash2=hash2*100019+v[i].y;
hash2%=998244353;
}
}
思路2
我的思路直接STL排序去重, 但是不知道官方数据会不会卡时间.
#include<bits/stdc++.h>
using namespace std;
int n, m, a[509][509], h[509][509];
set<vector<pair<int,int> > > s[509][509];
vector<pair<int, int> > v;
int dx[]={1,-1,0,0}, dy[]={0,0,1,-1};
void dfs(int i,int j){
h[i][j] = 1;
v.push_back(make_pair(i,j));
for(int k=0;k<4;++k){
int x = i+dx[k], y = j+dy[k];
if(x<=n && x>=1 && y<=m && y>=1 && h[x][y]==0 && a[i][j] == a[x][y])
dfs(x, y);
}
}
void f(){
int a=v[0].first, b=v[0].second;
int c = a, d = b;
for(int i=0;i<v.size();++i){
a = min(a,v[i].first);
b = min(b,v[i].second);
c = max(c,v[i].first);
d = max(d,v[i].second);
}
for(int i=0;i<v.size();++i)
v[i].first-=a, v[i].second-=b;
sort(v.begin(), v.end());
s[c-a][d-b].insert(v);
}
int main(){
scanf("%d%d", &n, &m);
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
scanf("%d", &a[i][j]);
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
if(!h[i][j]){
v.clear();
dfs(i, j);
f();
}
int ans = 0;
for(int i=0;i<n;++i)
for(int j=0;j<m;++j)
ans += s[i][j].size();
printf("%d", ans);
}