2020杭电多校第七场

T1007 Game

 

如果先手初始点在距离最远的点对上,那么先手必胜,据此,可以推广到距离次远的点对,距离第三远的点对,先手都是必胜的。所以点数是偶数时先手必胜,点数是奇数时先手如果在:除距离最长、距离次长、距离第三长...剩下的最后一个点上,那么先手必败,否则先手必胜。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int N=2010;
 5 struct node{
 6     int u,v;
 7     double d;
 8 }a[N*N];
 9 struct Point{
10     double x,y;
11 };
12 Point p[N];
13 bool vis[N];
14 bool cmp(const node &a,const node &b){
15     return a.d>b.d;
16 }
17 double dis(Point A,Point B){//两点间的距离 
18     return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));
19 }
20 int main()
21 {
22     int T;
23     scanf("%d",&T);
24     while(T--){
25         memset(vis,0,sizeof(vis));
26         int n;
27         scanf("%d",&n);
28         for(int i=1;i<=n;i++){
29             scanf("%lf%lf",&p[i].x,&p[i].y);
30         }
31         if(n%2==0){
32             printf("YES\n");
33             continue;
34         }
35         int cnt=0;
36         for(int i=1;i<=n;i++){
37             for(int j=i+1;j<=n;j++){
38                 a[++cnt].u=i;
39                 a[cnt].v=j;
40                 a[cnt].d=dis(p[i],p[j]);
41             }
42         }
43         sort(a+1,a+cnt+1,cmp);
44         int num=0;
45         for(int i=1;i<=cnt;i++){
46             int u=a[i].u,v=a[i].v;
47             if(!vis[u]&&!vis[v]){
48                 vis[u]=vis[v]=1;
49                 ++num;
50                 if(num==n/2) break;
51             }
52         }
53         if(vis[1]) printf("YES\n");
54         else printf("NO\n");
55     }
56     return 0;
57 }

 

T1009 Increasing and Decreasing

队友过的,代码先贴上。

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 
 5 int n,x,y;
 6 int a[100009]; 
 7 
 8 int main(){
 9     int t;
10     cin>>t;
11     while(t--){
12         scanf("%d%d%d",&n,&x,&y);
13         int pos=n;
14         if((x==1&&y!=n)||(y==1&&x!=n)||(x+y>n+1)){
15             cout<<"NO"<<endl;
16             continue;
17         }
18         while(pos>y){
19             int po=pos;
20             for(int i=y-1;i>=0;i--){
21                 a[pos]=po-i;
22                 pos--;
23             }
24         }//printf("%d",a[1]);
25         //for(int i=2;i<=n;i++)printf(" %d",a[i]);cout<<endl;
26         int u=n/y;
27         if(u*y==n)u--;
28         int l=n-y*u;
29         while(l+u<x)l+=y,u--;
30         int r=x-u;
31         //cout<<l<<endl;
32         for(int i=1;i<r;i++){
33             a[i]=i;
34         }
35         a[r]=l;
36         for(int i=r+1;i<=a[r];i++){
37             a[i]=--l;
38         }
39         printf("YES\n");printf("%d",a[1]);
40         for(int i=2;i<=n;i++)printf(" %d",a[i]);cout<<endl;
41         
42     }
43     return 0;
44 }

 

T1010 Jogging

队友想出来的,本质上就是:分母是:符合条件的点形成的一个连通块,连通块中所有的点周围可以到达的点(包括自己)的个数之和,分子就是起始点周围可以到达的点(包括自己)的个数之和。

如果连通块包含了对角线上的点(即x=y的点),说明可以到达无穷远,从而回到初始点的概率可以视为0。

从起始点bfs统计即可。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int d[8][2]={1,0,0,1,-1,0,0,-1,1,1,1,-1,-1,1,-1,-1};
 5 map<pair<ll,ll>,int>mp;
 6 ll num; //分母
 7 struct node{
 8     ll x,y;
 9     node(ll a,ll b){
10         x=a,y=b;
11     }
12 };
13 bool bfs(ll dx,ll dy){
14     num=0;
15     mp.clear();
16     queue<node>q;
17     q.push(node(dx,dy));
18     mp[make_pair(dx,dy)]=1;
19     while(!q.empty()){
20         node u=q.front();
21         q.pop();
22         if(u.x==u.y){
23             return 0;
24         }
25         ll tmp=0;
26         for(int i=0;i<8;i++){
27             ll nx=u.x+d[i][0];
28             ll ny=u.y+d[i][1];
29             if(__gcd(nx,ny)==1){
30                 continue;
31             }
32             tmp++;
33             if(!mp[make_pair(nx,ny)]){
34                 mp[make_pair(nx,ny)]=1;
35                 q.push(node(nx,ny));
36             }
37         }
38         num+=tmp+1;
39     }
40     return 1;
41 }
42 int main()
43 {
44     int T;
45     scanf("%d",&T);
46     while(T--){
47         ll sx,sy;
48         scanf("%lld%lld",&sx,&sy);
49         if(bfs(sx,sy)){
50             ll tmp=0; //分子
51             for(int i=0;i<8;i++){
52                 ll nx=sx+d[i][0];
53                 ll ny=sy+d[i][1];
54                 if(__gcd(nx,ny)>1){
55                     tmp++;
56                 }
57             }
58             tmp++;
59             ll c=__gcd(tmp,num); //化成最简形式
60             ll u=tmp/c,v=num/c;
61             printf("%lld/%lld\n",u,v);
62         }
63         else printf("0/1\n");
64     }
65     return 0;
66 }

 

posted @ 2020-08-12 15:59  --HY--  阅读(341)  评论(0编辑  收藏  举报