2018 ACM 國際大學生程序設計競賽上海大都會部分題解
阿新 • • 發佈:2018-08-05
eof long long print 1.0 mat 數位dp vector perf 設計
題目鏈接
2018 ACM 國際大學生程序設計競賽上海大都會
下午午休起床被同學叫去打比賽233
然後已經過了2.5h了
先挑過得多的做了
....
A題
rand x*n 次點,每次judge一個點位端點的共線向量數判斷是否大於給定x
強行rand 500次
代碼
#include<bits/stdc++.h> using namespace std; inline int read() { int x = 0,f = 1; char c = getchar(); while(c < '0' || c > '9') {if(c == '-')f =- 1; c = getchar(); } while(c <= '9' &&c >= '0') x = x * 10 + c - '0',c = getchar(); return x * f; } const int maxn = 20007; #define eps (1e-13) double k; int n; struct points { int x,y; } p[maxn]; bool solve(int p1,int p2) { int tx = p[p1].x - p[p2].x,ty = p[p1].y - p[p2].y; int cnt = 2; for(int i = 1;i <= n;++ i) { if(i == p1 || i == p2) continue; int px = p[p1].x - p[i].x,py = p[p1].y - p[i].y; if((long long)tx * py - (long long)ty * px == 0) cnt ++; } double K = (double) cnt / (double) n; return (K >= k); } int main() { srand(time(0)); srand(rand()); int t = read(); while(t -- ) { n = read(); scanf("%lf",&k); for(int i = 1;i <= n;++ i) p[i].x = read(),p[i].y = read(); int p1,p2; bool flag = false; for(int i = 500;i --;) { p1 = rand() % n + 1; p2 = p1; while(p2 == p1) p2 = rand() % n + 1; if(solve(p1,p2)) { flag = true; break; } if(flag) break; } if(t != 0) { if(flag) puts("Yes"); else puts("No"); } if(t == 0) { if(flag)printf("Yes"); else printf("No"); } } return 0; }
B題
很sb的打了nlogn篩
代碼
#include<bits/stdc++.h> using namespace std; const int maxn = 200000; vector<int>vec[maxn + 10]; int num[maxn + 10]; int main() { for(int i = 1;i <= maxn;++ i) { for(int j = i;j <= maxn;j += i) { num[j] += i;vec[j].push_back(i); } } int t; scanf("%d",&t); int cas = 0; while(t --) { cas++; int k ; scanf("%d",&k); printf("Case %d: ",cas); if(num[k] - k != k) { if(k != 0)puts("Not perfect."); else printf("Not perfect."); } else { int p = vec[k].size() - 1; printf("%d = ",k); for(int i = 0;i < p;++ i) { if(i != p - 1)printf("%d + ",vec[k][i]); else printf("%d",vec[k][i]); } if(t != 0)puts(""); } } return 0; }
D題Thinking-Bear magic
發現每次面積變為原來的$\frac{1}{\cos(\frac{\pi}{n})^2} $
代碼
#include<bits/stdc++.h> #define Pi 3.14159265359 double Sin(int n){ return sin((2.0*Pi)/n); } double Cos(int n){ return cos((2.0*Pi)/n); } double Tan(int n){ return tan((2.0*Pi)/n); } double S(int n, double R) { return ((0.25*n*R*R)/(double)tan(Pi/n)); } double calc(int n){ return cos(Pi/(1.0*n))*cos(Pi/(1.0*n)); } int main () { int T,n,a,l; scanf("%d",&T); double s; int t; while(T --) { scanf("%d%d%d",&n,&a,&l); double gg = calc(n); t = 0; s = S(n,(double)a); while(s > l) s = gg * s, ++ t; printf("%d\n",t); } return 0; }
J題目 Beautiful Numbers
數位dp
代碼
#include<bits/stdc++.h>
using namespace std;
inline int read() {
int x = 0,f = 1;
char c = getchar();
while(c < '0' || c > '9')c = getchar();
while(c <= '9' && c >= '0') x = x * 10 + c - '0', c = getchar();
return x * f;
}
const int maxn=3e5+5;
const int INF =0x3f3f3f3f;
#define LL long long
int a[20];
LL dp[13][105][150];
int mod;
LL dfs(int pos,int sum,int res,bool limit) {
if(pos == -1) return (sum == mod && !res);
if(dp[pos][sum][res] != -1 && !limit) return dp[pos][sum][res];
int up = limit ? a[pos] : 9;
LL res = 0;
for(int i = 0;i <= up;++ i) {
if(i + sum > mod) break;
res += dfs(pos - 1,sum + i,(res * 10 + i) % mod,limit && i == a[pos]);
}
if(!limit) dp[pos][sum][res] = res;
return res;
}
LL solve(LL n) {
int pos=0;
LL x = n;
while(x) a[pos ++] = x % 10, x /= 10;
LL res = 0;
for(int i = 1;i <= 9 * pos;++ i) {
mod = i;
memset(dp,-1,sizeof(dp));
res += dfs(pos-1,0,0,true);
}
return res;
}
int main() {
int T = read();
int cas = 0;
while(T --) {
cas ++;
LL n = read();
printf("Case %d: %lld\n",cas,solve(n));
}
return 0;
}
K題 Matrix Multiplication
矩乘裸題
代碼
#include<bits/stdc++.h>
using namespace std;
struct MMMM {
int m[21][21];
int r,c;
MMMM() {}
MMMM(int n) {memset(m, false, sizeof m);r = c = n; for (int i = 0; i < r; i +=1) m[i][i] = 1;}
MMMM(int R,int C) {memset(m, false, sizeof m);r = R,c = C;}
MMMM operator * (const MMMM & o)const {
MMMM res = MMMM(r, o.c);
for (int i = 0; i< r;i += 1)
for (int j = 0 ;j < o.c; j += 1)
for (int k = 0; k < c; k += 1 )
res.m[i][j] += 1ll * m[i][k] * o.m[k][j];
return res;
}
void print() {
for (int i =0 ;i < r;i += 1) {
for (int j = 0; j < c; j += 1) {
if(j!=c-1)printf("%d ",m[i][j]);
else printf("%d",m[i][j]);
}
puts("");
}
}
void input() {
for (int i = 0; i< r; i += 1)
for (int j = 0; j < c; j += 1)
scanf("%d", &m[i][j]);
}
};
int main () {
int T;
scanf("%d",&T);
for (int i =1; i <= T; i += 1) {
int r1,c1,r2,c2;
scanf("%d%d%d%d", &r1,&c1,&r2,&c2);
MMMM a,b;
a=MMMM(r1,c1), b= MMMM(r2,c2);
a.input(); b.input();
printf("Case %d:\n",i);
if (c1 != r2) {
printf("ERROR\n");
continue;
}
MMMM c = a * b;
c.print();
}
return 0;
}
2018 ACM 國際大學生程序設計競賽上海大都會部分題解