【LOJ】#2076. 「JSOI2016」炸彈攻擊
阿新 • • 發佈:2018-08-27
題解 type circle open [] long long 模擬退火 oid orm
題解
我冷靜一下,話說如果去掉建築和R的限制好像是模擬退火吧
然後開始寫模擬退火了,起始點就隨機一個敵人作為起始點
沒對著數據寫了一下獲得了70pts,感到美滋滋
然後對著數據卡了很久……發現有個數據點似乎需要從初始溫度小一點的情況開始跳,於是就10次從20000降溫,10次從2000降溫
AC啦
該題的AC率顯著地下降了= =
代碼
#include <bits/stdc++.h> #define enter putchar(‘\n‘) #define space putchar(‘ ‘) #define pii pair<int,int> #define fi first #define se second #define mp make_pair #define MAXN 100005 #define mo 99994711 #define pb push_back #define eps 1e-8 //#define ivorysi using namespace std; typedef long long int64; typedef unsigned int u32; typedef double db; template<class T> void read(T &res) { res = 0;T f = 1;char c = getchar(); while(c < ‘0‘ || c > ‘9‘) { if(c == ‘-‘) f = -1; c = getchar(); } while(c >= ‘0‘ && c <= ‘9‘) { res = res * 10 + c - ‘0‘; c = getchar(); } res *= f; } template<class T> void out(T x) { if(x < 0) {x = -x;putchar(‘-‘);} if(x >= 10) out(x / 10); putchar(‘0‘ + x % 10); } int dx[] = {0,-1,0,1}; int dy[] = {1,0,-1,0}; struct Point { db x,y; Point() {} Point(db _x,db _y) {x = _x;y = _y;} friend Point operator + (const Point &a,const Point &b) {return Point(a.x + b.x,a.y + b.y);} friend Point operator - (const Point &a,const Point &b) {return Point(a.x - b.x,a.y - b.y);} friend Point operator * (const Point &a,const db &d) {return Point(a.x * d,a.y * d);} friend Point operator / (const Point &a,const db &d) {return Point(a.x / d,a.y / d);} friend db operator * (const Point &a,const Point &b) {return a.x * b.y - a.y * b.x;} friend db dot(const Point &a,const Point &b) {return a.x * b.x + a.y * b.y;} db norm() {return sqrt(x * x + y * y);} }Enemy[1005]; struct circle { Point O;db r; }C[15]; u32 Rand() { static u32 x = 20020421; return x += x << 2 | 1; } db Rand_range() { return (db)(Rand() % 10000) / 10000.0; } int N,M,ans; db R; void Init() { read(N);read(M);scanf("%lf",&R); db x,y,r; for(int i = 1 ; i <= N ; ++i) { scanf("%lf%lf%lf",&x,&y,&r); C[i].O = Point(x,y);C[i].r = r; } for(int i = 1 ; i <= M ; ++i) { scanf("%lf%lf",&x,&y); Enemy[i] = Point(x,y); } } int Count(Point x) { db r = R; for(int i = 1 ; i <= N ; ++i) { r = min(r,(C[i].O - x).norm() - C[i].r); } int cnt = 0; for(int i = 1 ; i <= M ; ++i) { if((Enemy[i] - x).norm() <= r + eps) ++cnt; } return cnt; } void Solve(int num) { db T = num,delta = 0.99; Point x = Enemy[Rand() % M + 1]; int tmp = 0; while(T > 0.01) { Point t;tmp = 0; for(int i = 0 ; i <= 3 ; ++i) { Point k = x + Point(T * dx[i],T * dy[i]); int a = Count(k); if(a > tmp) {t = k;tmp = a;} } if(tmp > ans) {x = t;ans = tmp;} else if(exp((ans - tmp) * 0.1 / T) > Rand_range()) x = t; T *= delta; } } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Init(); ans = 1; int cnt = 10; while(cnt--) Solve(20000); cnt = 10; while(cnt--) Solve(2000); out(ans);enter; return 0; }
【LOJ】#2076. 「JSOI2016」炸彈攻擊