OYBDOOO

2022年安徽省机器人大赛-程序设计赛道网络预赛-本科组题解

 

纪念freedive第一次AK的比赛,只不过数据是真的有问题……


A

题目信息:给两个数a、b,可以对a进行如下的操作:a = a + x,x是任意的大于0的奇数, a = a - y, y是任意的大于0的偶数。可以执行任意次数以上的操作。问从a变成b最少需要几次操作?O(1)

 1 #include <iostream>
 2 using namespace std;
 3 
 4 int main()
 5 {
 6     long long t, a, b;
 7     cin >> t;
 8     while(t--)
 9     {
10         cin >> a >> b;
11         if(a == b) {
12             cout << 0 << endl;
13         } else if(a > b) {
14             cout << (((a - b) & 1) ? 2 : 1) << endl;
15         } else {
16             cout << (((a - b) & 1) ? 1 : 2) << endl;
17         }
18     }
19 }

 

B

题目信息:定义数组中的某个数ai如果是特殊的,则满足:在数组中存在一个长度大于等于2的连续子序列,其和为ai。给你一个长度为n的数组,问有多少数是特殊的。O(玄学)

 1 #include <cstdio>
 2 #include <set>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 const int N = 8003;
 7 int n, t, a[N], pre[N];
 8 int main()
 9 {
10     scanf("%d", &t);
11     while(t--)
12     {
13         scanf("%d", &n);
14         set<int> num;
15         for(int i = 1; i <= n; ++i)
16         {
17             scanf("%d", &a[i]);
18             num.insert(a[i]);
19             pre[i] = pre[i - 1] + a[i];
20         }
21         for(int i = 0; i < n - 1; ++i)
22         {
23             int j = i + 2;
24             while(j <= n)
25             {
26                 int sum = pre[j] - pre[i];
27                 num.erase(sum);
28                 set<int>::iterator it = num.upper_bound(sum);
29                 if(it == num.end())
30                     break;
31                 else
32                     j = lower_bound(pre + 1, pre + 1 + n, (*it) + pre[i]) - pre;
33             }
34         }
35         int ans = 0;
36         for(int i = 1; i <= n; ++i)
37             if(num.find(a[i]) == num.end())
38                 ans++;
39         printf("%d\n", ans);
40     }
41 }

 

C

题目信息:给一个长方体,可以由两个对角顶点坐标确定,一个顶点位于原点(0,0,  0),另一个顶点在点(x1, y1, z1)处。盒子的六个面编号为a1, a2, ..., a6,每个面的正中央印有一个数字x。编号位于框上,如下所示:数字a1写在ZOX平面上的面上;a2写在与a1所在的平面平行的面上;a3写在XOY平面上的面上;a4写在与a3所在的平面平行的面上;a5写在YOZ平面上的面上;a6写在与a5所在的平面平行的面上;此时,你在(x, y, z)处看长方体。请注意,长方体的所有面都不是透明的,你无法通过长方体看到数字且你能看得足够远,求出你能看清所看到的面上数字,求能看到的数字之和。O(1)

 1 #include <iostream>
 2 using namespace std;
 3 int main() {
 4     int x, y, z, X, Y, Z, a1, a2, a3, a4, a5, a6, ans = 0;
 5     cin >> x >> y >> z >> X >> Y >> Z >> a1 >> a2 >> a3 >> a4 >> a5 >> a6;
 6     if(x < 0) ans += a5; else if (x > X) ans += a6;
 7     if(y < 0) ans += a1; else if (y > Y) ans += a2;
 8     if(z < 0) ans += a3; else if (z > Z) ans += a4;
 9     cout << ans << endl;
10 }

D

题目信息:有2N张牌,它们的点数分别为1到2N。小柯拿了其中的N张,小鹏拿了剩下的N张. 小柯和小鹏会进行N轮游戏,在每轮游戏中,小柯和小鹏各出一张牌。出了的牌不能收回。每轮谁的牌点数大谁就赢; 已知小鹏每一轮会出什么牌,试求小柯最多能赢多少轮。O(n)

 1 #include <algorithm>
 2 #include <iostream>
 3 using namespace std;
 4 
 5 const int N = 100005;
 6 int n, ans = 0;
 7 char book[2 * N];
 8 int main()
 9 {
10     cin >> n;
11     for(int i = 0, x; i < n; ++i)
12     {
13         cin >> x;
14         book[x] = 1;
15     }
16     for(int i = 1, j = 1; i <= 2 * n; ++i)
17         if(book[i] == 1) {
18             j = max(j, i + 1);
19             while(book[j] != 0 && j <= 2 * n)
20                 ++j;
21             if(j > 2 * n)
22                 break;
23             book[j] = 2;
24             ans++;
25         }
26     printf("%d\n", ans);
27     return 0;
28 }

E

题目信息:小怡开了一家蛋糕店,她有n个顾客,每位顾客i都有一个喜好的甜度值a[i](1<=i<=n)。甜度为k的蛋糕,当且仅当|a[i]-k|<=p 时,顾客i才能得到满足。给定n个顾客喜好的甜度值,小怡想知道最多可以让多少顾客得到满足。O(n)

 1 #include <cstdio>
 2 #include <algorithm>
 3 using namespace std;
 4 
 5 const int N = 1000010;
 6 int n, p, ans = 1, a[N];
 7 int main()
 8 {
 9     scanf("%d %d", &n, &p);
10     for(int i = 1; i <= n; ++i)
11         scanf("%d", a + i);
12     sort(a + 1, a + 1 + n);
13     for(int i = 1, j = 1; i <= n; ++i) {
14         for(; j <= n && a[j] - a[i] <= 2 * p; ++j);
15         ans = max(ans , j - i);
16     }
17     printf("%d\n", ans);
18     return 0;
19 }

F

题目信息:给N(1<=N<=30)个正整数,好奇的小明想知道这N个正整数的乘积,是否可以将其分解为2个正整数a和b的乘积,并且a的约数个数与b的约数个数之差为 1 个。O(玄学)(tip:约数一奇一偶,优化时间)

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 const int maxn=1e6+100;
 5 ll a[maxn],aa[maxn],bb[maxn],cc[maxn],n,sc=0,ttt;
 6 void dfs(int x){
 7     ll i,j;
 8     if(x==ttt+1){
 9     //    if(cc[1]==2&&cc[2]==0&&cc[3]==0)
10     //        int my=-1;
11         ll all=1,al=1,A=1,B=1;
12         for(i=1;i<=ttt;i++)
13             all=all*(cc[i]+1ll),al=al*((bb[i]-cc[i])+1ll);
14         if(all-al==1){
15             for(i=1;i<=ttt;i++)
16                 for(j=1;j<=cc[i];j++)
17                     A=A*aa[i];
18             for(i=1;i<=ttt;i++)
19                 for(j=1;j<=bb[i]-cc[i];j++)
20                     B=B*aa[i];
21             printf("%lld %lld\n",A,all);
22             printf("%lld %lld",B,al);
23             sc=1;
24             return;
25         }else if(al-all==1){
26             for(i=1;i<=ttt;i++)
27                 for(j=1;j<=cc[i];j++)
28                     A=A*aa[i];
29             for(i=1;i<=ttt;i++)
30                 for(j=1;j<=bb[i]-cc[i];j++)
31                     B=B*aa[i];
32             printf("%lld %lld\n",B,al);
33             printf("%lld %lld",A,all);
34             sc=1;
35             return;
36         }else return;
37     }
38     if(sc==1)return;
39     for(i=0;i<=bb[x];i+=2){
40         cc[x]=i;
41         if(sc==1)return;
42         dfs(x+1);
43         if(sc==1)return;
44     }
45     if(sc==1)return;
46 }
47 map<ll,ll>mp;
48 int main(){
49     ll i,j;
50     scanf("%lld",&n);
51     for(i=1;i<=n;i++){
52         scanf("%lld",&a[i]);
53         for(j=2;j*j<=a[i];j++){
54             while(a[i]%j==0){
55                 mp[j]++;
56                 a[i]/=j;
57             }
58         }if(a[i]>1)mp[a[i]]++;
59     }
60     ttt=0;
61     map<ll,ll>::iterator it;
62     for(it=mp.begin();it!=mp.end();it++){
63         ttt++;
64         aa[ttt]=it->first;
65         bb[ttt]=it->second;
66     }
67     dfs(1);
68     return 0;
69 }

G

题目信息:小星是参加防疫的一名志愿者,每天都为在家中被隔离的居民们送蔬菜包。他把每层楼看成一个n*n的矩阵。小星需要将蔬菜包送到位于m层的居民手中,小星想请你帮他计算一下,他能否成功将蔬菜送达。如果能则需要的最少体力,如果不能则输出No。大暴力……累死我了

  1 #include<bits/stdc++.h>
  2 #define mp make_pair
  3 using namespace std;
  4 int n,m,tot=0;
  5 int dx[5]={0,-1,1,0,0};
  6 int dy[5]={0,0,0,-1,1};
  7 const int maxn=1e5+10;
  8 int gg(int x,int y,int z){
  9     return (x-1)*n*n+(y-1)*n+z;
 10 }
 11 int pp(int x,int y){
 12     if(x<1||y<1||x>n||y>n)return 0;
 13     else return 1;
 14 }
 15 struct EDGE{
 16     int v,next,quan;
 17 }edge[500010];
 18 int ind[maxn],vist[maxn],dist[maxn],st,ed;
 19 char ss[55][55][55];
 20 void add(int aa,int bb,int cc){
 21     tot++;
 22     edge[tot].v=bb;
 23     edge[tot].quan=cc;
 24     edge[tot].next=ind[aa];
 25     ind[aa]=tot;
 26 }
 27 void dij(){
 28     int i;
 29     priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > >pq;
 30     memset(dist,127,sizeof(dist));
 31     dist[st]=0;
 32     pq.push(mp(0,st));
 33     while(!pq.empty()){
 34         int u=pq.top().second;
 35         pq.pop();
 36         if(vist[u])continue;
 37         vist[u]=1;
 38         for(i=ind[u];i!=-1;i=edge[i].next){
 39             int v=edge[i].v;
 40             if(vist[v])continue;
 41             if(dist[v]>dist[u]+edge[i].quan){
 42                 dist[v]=dist[u]+edge[i].quan;
 43                 pq.push(mp(dist[v],v));
 44             }
 45         }
 46     }
 47 }
 48 int main(){
 49     int o,i,j,a,b;
 50     memset(ind,-1,sizeof(ind));
 51     scanf("%d%d",&m,&n);
 52     for(o=1;o<=m;o++){
 53         for(i=1;i<=n;i++)
 54             scanf("%s",ss[o][i]+1);
 55         for(i=1;i<=n;i++){
 56             for(j=1;j<=n;j++){
 57                 //if(i==2&&j==1)
 58                 //    int my=-1;
 59                 if(ss[o][i][j]=='#')continue;
 60                 for(a=1;a<=4;a++){
 61                     int ni=i+dx[a],nj=j+dy[a];
 62                     int ppp=0;
 63                     if(!pp(ni,nj))continue;
 64                     if(ss[o][ni][nj]=='.'||ss[o][ni][nj]=='E'||ss[o][ni][nj]=='S'||ss[o][ni][nj]=='U'){
 65                         add(gg(o,i,j),gg(o,ni,nj),1);
 66                         ppp=1;
 67                     }
 68                     if(ss[o][ni][nj]=='#'){
 69                         ppp=2;
 70                     }
 71                     if(ppp==2){
 72                         int nni=ni+dx[a],nnj=nj+dy[a];
 73                         if(nni==i&&nnj==j)continue;
 74                         if(!pp(nni,nnj))continue;
 75                         if(ss[o][nni][nnj]=='.'||ss[o][nni][nnj]=='E'||ss[o][nni][nnj]=='S'||ss[o][nni][nnj]=='U')
 76                             add(gg(o,i,j),gg(o,nni,nnj),3);
 77                     }
 78                     else{
 79                         for(b=1;b<=4;b++){
 80                             int nni=ni+dx[b],nnj=nj+dy[b];
 81                             if(nni==i&&nnj==j)continue;
 82                             if(!pp(nni,nnj))continue;
 83                             if(ss[o][nni][nnj]=='.'||ss[o][nni][nnj]=='E'||ss[o][nni][nnj]=='S'||ss[o][nni][nnj]=='U')
 84                                 add(gg(o,i,j),gg(o,nni,nnj),1);
 85                             }
 86                         }
 87                     }
 88                 }
 89             }
 90         }
 91     int tmp=m*n*n+5;
 92     for(o=1;o<m;o++){
 93 //        int aa,bb,cc,dd;
 94     //    tmp++;
 95         for(i=1;i<=n;i++)for(j=1;j<=n;j++)if(ss[o][i][j]=='U'){
 96             add(gg(o,i,j),gg(o+1,i,j),0);
 97         }
 98     }
 99     for(i=1;i<=n;i++)for(j=1;j<=n;j++){
100         if(ss[1][i][j]=='S')st=gg(1,i,j);
101         if(ss[m][i][j]=='E')ed=gg(m,i,j);
102     }
103     dij();
104     if(dist[ed]==dist[0])printf("No");
105     else printf("%d",dist[ed]);
106     return 0;
107 }

H

题目信息:小星是参加防疫的一名志愿者,每天都为在家中被隔离的居民们送蔬菜包。他把每层楼看成一个n*n的矩阵。小星需要将蔬菜包送到位于m层的居民手中,小星想请你帮他计算一下,他能否成功将蔬菜送达。如果能则需要的最少体力,如果不能则输出No。O(n)

 1 #include <cstdio>
 2 #include <map>
 3 using namespace std;
 4 
 5 const int N = 200010;
 6 int n, a[N], k, ans = 0;
 7 map<int, int> bk;
 8 int main()
 9 {
10     scanf("%d", &n);
11     for(int i = 1, x; i <= n; ++i)
12     {
13         scanf("%d", &x);
14         a[i] = a[i - 1] ^ x;
15     }
16     scanf("%d", &k);
17     bk[0] = 1;
18     for(int i = 1; i <= n; ++i)
19     {
20         ans += bk[a[i]^k];
21         bk[a[i]]++;
22     }
23     printf("%d\n", ans);
24     return 0;
25 }

 

posted on 2022-05-17 22:29  OYBDOOO  阅读(1166)  评论(0编辑  收藏  举报

导航