| 比赛 |
csp2025模拟练习2 |
评测结果 |
AAAAAAAAAAAAAAAAAAAA |
| 题目名称 |
愤怒的小鸟 |
最终得分 |
100 |
| 用户昵称 |
淮淮清子 |
运行时间 |
10.828 s |
| 代码语言 |
C++ |
内存使用 |
4.19 MiB |
| 提交时间 |
2025-10-29 11:10:57 |
显示代码纯文本
#include<bits/stdc++.h>
#include<random>
using namespace std;
const double EPS = 1e-7;
double x[20], y[20];
int n, T, m;
vector<int> masks;
unordered_set<int> st;
mt19937 rng(time(NULL));
int rnd(int l, int r){
return uniform_int_distribution<int>(l, r)(rng);
}
int Get(int i, int j){
if(fabs(x[i] - x[j]) < EPS){
return 0;
}
double x_1 = x[i], x_2 = x[j];
double y_1 = y[i], y_2 = y[j];
double a = (y_1 * x_2 - y_2 * x_1) / (x_1 * x_2 * (x_1 - x_2));
if(a >= -EPS){
return 0;
}
double b = y_1 / x_1 - a * x_1;
int mask = 0;
for(int k = 0;k < n;k ++){
double cyc = a * x[k] * x[k] + b * x[k];
if(fabs(cyc - y[k]) < EPS){
mask |= (1 << k);
}
}
return mask;
}
int SA(){
masks.clear();
st.clear();
for(int i = 0;i < n;i ++){
int mask = (1 << i);
masks.push_back(mask);
st.insert(mask);
}
for(int i = 0;i < n;i ++){
for(int j = i + 1;j < n;j ++){
int mask = Get(i, j);
if(mask && !st.count(mask)){
masks.push_back(mask);
st.insert(mask);
}
}
}
int bk = (1 << n) - 1;
int ans = n, cnt;
vector<int> cur;
int cov = 0;
while(cov != bk){
int bt = 0, nw = -1;
for(int m : masks){
int ncov = __builtin_popcount(m & ~cov);
if(ncov > nw){
nw = ncov;
bt = m;
}
}
cur.push_back(bt);
cov |= bt;
}
cnt = cur.size();
ans = min(ans, cnt);
double temp = 50.0;
double dec = 0.85;
int p = 100 * n;
while(temp > EPS){
for(int k = 0;k < p;k ++){
vector<int> nw_cur = cur;
int op = rnd(0, 3);
if(op == 0){
if(nw_cur.empty() || masks.empty()) continue;
int idx = rnd(0, nw_cur.size() - 1);
int nm = masks[rnd(0, masks.size() - 1)];
nw_cur[idx] = nm;
int tot = 0;
for(int m : nw_cur) tot |= m;
if(tot == bk){
int nc = nw_cur.size();
if(nc < cnt || (double)rnd(0, RAND_MAX)/RAND_MAX < exp((cnt - nc)/temp)){
cur = nw_cur;
cnt = nc;
}
}
}
else if(op == 1){
if(nw_cur.size() <= 1 || masks.empty()) continue;
int idx = rnd(0, nw_cur.size() - 1);
nw_cur.erase(nw_cur.begin() + idx);
int c = 0;
for(int m : nw_cur) c |= m;
int bt = 0, mx = -1;
for(int m : masks){
int add = __builtin_popcount(m & ~c);
if(add > mx) mx = add, bt = m;
}
if(mx <= 0) continue;
nw_cur.push_back(bt);
int tot = 0;
for(int m : nw_cur) tot |= m;
if(tot == bk){
int nc = nw_cur.size();
if(nc < cnt || (double)rnd(0, RAND_MAX)/RAND_MAX < exp((cnt - nc)/temp)){
cur = nw_cur;
cnt = nc;
}
}
}
else if(op == 2){
if(nw_cur.size() < 2) continue;
int i = rnd(0, nw_cur.size() - 1);
int j = rnd(0, nw_cur.size() - 1);
if(i == j) continue;
if(i > j) swap(i, j);
int comb = nw_cur[i] | nw_cur[j];
if(!st.count(comb)) continue;
nw_cur.erase(nw_cur.begin() + j);
nw_cur.erase(nw_cur.begin() + i);
nw_cur.push_back(comb);
int nc = nw_cur.size();
if(nc < cnt || (double)rnd(0, RAND_MAX)/RAND_MAX < exp((cnt - nc)/temp)){
cur = nw_cur;
cnt = nc;
}
}
else{
if(nw_cur.empty()) continue;
int idx = rnd(0, nw_cur.size() - 1);
int m = nw_cur[idx];
if(__builtin_popcount(m) <= 1) continue;
int p1 = 0;
for(int bit = 0;bit < n;bit ++){
if(m & (1 << bit) && rnd(0, 1)) p1 |= (1 << bit);
}
if(p1 == 0 || p1 == m) continue;
int p2 = m ^ p1;
if(!st.count(p1) || !st.count(p2)) continue;
nw_cur.erase(nw_cur.begin() + idx);
nw_cur.push_back(p1);
nw_cur.push_back(p2);
int nc = nw_cur.size();
if(nc <= cnt + 1 && (nc < cnt || (double)rnd(0, RAND_MAX)/RAND_MAX < exp((cnt - nc)/temp))){
cur = nw_cur;
cnt = nc;
}
}
ans = min(ans, cnt);
}
temp *= dec;
}
return ans;
}
int main(){
freopen("angrybirds.in", "r", stdin);
freopen("angrybirds.out", "w", stdout);
ios::sync_with_stdio(0);
cin.tie(0);
cin >> T;
while(T --){
cin >> n >> m;
for(int i = 0;i < n;i ++){
cin >> x[i] >> y[i];
}
cout << SA() << '\n';
}
return 0;
}