省选考前单挑做点ACM练练细节还是很不错的嘛~

福利:http://codeforces.com/gym/101350

先来放上惨不忍睹的virtual participate成绩(中间跑去食堂吃饭于是浪费了一点时间)

Problem A DNF

Problem B 1Y(5min)

Problem C 1Y(37min)

Problem D 2Y(9min)

Problem E 4Y(3h58min)

Problem F DNF

Problem G 1Y(4h13min)

Problem H 1Y(13min)

Problem I 1Y(1h7min)

Problem J 1Y(1h26min)

Problem K 1Y(2h36min)

Problem L DNF

Problem M 30Y(3h47min)

先来大体上说一下,整个5h都还算ok,然而这个M题。。。事故啊。。。(之后会说)

感觉这套题有点偏向化,思维量大代码量小,导致容易卡题,也容易柳暗花明。

下面就是题解啦~

Problem A:

这是一个很不错的思维题啊!

比较容易陷入误区的地方在于,这种三元集的题大部分人会先去考虑中间项,然而应该先考虑两边。

我们将1的个数前缀和一下,于是观察出如果(i,j,k)满足题意,那么presum[i]和presum[k]有一些奥妙重重的关系,

然后又发现一个惊人的事实:如果presum[i]和presum[k]满足的话,那么中间的j应该是有且仅有1个可能的,

这样就可以统计答案了。

时间复杂度O(n),代码如下:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long int64;
 4 const int N=220000;
 5 int n, z[N], num=0;
 6 char c[N];
 7 int64 calc ()
 8 {
 9     int64 ans=0;
10     int cnt=0;
11     for (int i=0; i<(int)strlen(c); i++) if (c[i]=='0') cnt++;
12     else z[++num]=cnt+1, cnt=0;
13     z[++num]=cnt+1;
14     int64 a=0, b=0;
15     for (int i=1; i<=num; i=i+2) a+=z[i];
16     for (int i=2; i<=num; i=i+2) b+=z[i];
17     ans=a*b;
18     for (int i=1; i<=num; i++) ans-=2*z[i];
19     ans+=z[1]+z[num];
20     ans+=num-1;
21     return ans;
22 }
23 int main ()
24 {
25     int t, n;
26     scanf("%d", &t);
27     for (int i=1; i<=t; i++)
28     {
29         scanf("%d%s", &n, c);
30         num=0;
31         printf("%I64d\n", calc());
32     }
33     return 0;
34 }

Problem B:

你会不会写程序呀~

你会不会比大小呀~

时间复杂度O(1),代码如下:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int main()
 4 {
 5     int T;
 6     cin>>T;
 7     while (T--)
 8     {
 9         int a,b;
10         cin>>a>>b;
11         if (b>a) cout<<"WeWillEatYou"<<endl; else cout<<"FunkyMonkeys"<<endl;
12     }
13     return 0;
14 }

Problem C:

首先这个题有两问,

第一问的答案就是这n个数的总和,O(n)扫一下就好啦~

第二问的答案就是这n个数的最大公约数,O(n)扫一下也好啦~

时间复杂度O(n),代码如下:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int T,n;
 4 int x[100007];
 5 long long ans1,ans2;
 6 int read()
 7 {
 8     int x=0,f=1;char ch=getchar();
 9     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
10     while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
11     return x*f;
12 }
13 long long gcd(long long a,long long b)
14 {
15     if (b==0) return a;
16     return gcd(b,a%b);
17 }
18 int main()
19 {
20     T=read();
21     while (T--)
22     {
23         n=read();
24         ans1=0,ans2=0;
25         for (int i=1;i<=n;i++)
26         {
27             x[i]=read();
28             ans1+=x[i];
29             ans2=gcd(x[i],ans2);
30         }
31         cout << ans1 << ' ' << ans2 << endl;
32     }
33     return 0;
34 }

Problem D:

首先很容易发现,不管怎么操作,大家的相对奇偶性是不变的。

然后发现所有数奇偶性相同是答案为yes的充要条件。(因为不可能小于0啊,如果小于0的话先大家都长高一下就好了~)

时间复杂度O(n),代码如下:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int read()
 4 {
 5     int x=0,f=1;char ch=getchar();
 6     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
 7     while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
 8     return x*f;
 9 }
10 int T;
11 int h[100007];
12 int main()
13 {
14     cin>>T;
15     while (T--)
16     {
17         int n;
18         n=read();
19         for (int i=1;i<=n;i++) h[i]=read();
20         bool check=true;
21         for (int i=2;i<=n;i++) if (h[i]%2!=h[1]%2) check=false;
22         if (check) cout <<"yes" << endl; else cout << "no" << endl;
23     }
24     return 0;
25 }

Problem E:

这是个很有趣的题目呀~

大家千万不要被质数这个条件所迷惑啊,这题和这个一点关系也没有。

当n为偶数的时候,只需要先手取最中间两个,然后和后手对称取就能赢了,所以n>2且为偶数时,先手获胜。

当n为奇数的时候,只需要先手取最中间三个,然后和对手对称取就能赢了,所以n>3且为奇数时,先手获胜。

当n=1时,先手获胜。

当n=2时,先手只能取1,后手也取1,后手获胜。

当n=3时,先手只能取2,后手取1,后手获胜。

所以这个题只有n=2或者n=3的时候后手获胜,其他情况都是先手获胜。

自古博弈代码短~~~

时间复杂度O(1),代码如下:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int read()
 4 {
 5     int x=0,f=1;char ch=getchar();
 6     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
 7     while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
 8     return x*f;
 9 }
10 int T,n;
11 int main()
12 {
13     T=read();
14     while (T--)
15     {
16         n=read();
17         if (n==2||n==3) cout << "second" << endl; else cout << "first" << endl;
18     }
19     return 0;
20 }

Problem G:

这个题我是在比较靠后的时间去做的,

第一眼。。。smg。。。完全不会

第二眼。。。n和m这么大,连O(nm)都过不了。。。

第三眼。。。这个k怎么才20啊。。。这不是瞎容斥一下就好了。。。

我们枚举2^k种不同的情况,每个点能不能取,维护出x坐标最小最大值,y坐标最小最大值,剩下的全部数学手推即可。

时间复杂度O(2^k),代码如下:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int read()
 4 {
 5     int x=0,f=1;char ch=getchar();
 6     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
 7     while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
 8     return x*f;
 9 }
10 long long ans;
11 int T,n,m,k,minx,maxx,miny,maxy;
12 int x[25],y[25],path[25];
13 void dfs(int x1,int cnt)
14 {
15     if (x1<=k)
16     {
17         dfs(x1+1,cnt);
18         path[cnt+1]=x1;
19         dfs(x1+1,cnt+1);
20     } else if (cnt>0)
21     {
22         minx=100007,miny=100007;
23         maxx=0,maxy=0;
24         for (int i=1;i<=cnt;i++)
25         {
26             int t=path[i];
27             minx=min(minx,x[t]);
28             maxx=max(maxx,x[t]);
29             miny=min(miny,y[t]);
30             maxy=max(maxy,y[t]);
31         }
32         long long r=1LL*minx*miny*(n-maxx+1)*(m-maxy+1);
33         if (cnt%2==1) ans-=r; else ans+=r;
34     }
35 }
36 int main()
37 {
38     T=read();
39     while (T--)
40     {
41         n=read(),m=read(),k=read();
42         for (int i=1;i<=k;i++) x[i]=read(),y[i]=read();
43         ans=((1LL*n*(n-1))/2+n)*((1LL*m*(m-1))/2+m);
44         dfs(1,0);
45         cout << ans << endl;
46     }
47     return 0;
48 }

Problem H:

这个题模拟一下就好了吧,先扫一遍字母,再扫一遍看一下是否回文。

时间复杂度O(n),代码如下:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int T;
 4 string s;
 5 bool deal(char x)
 6 {
 7     if (x=='A'||x=='H'||x=='I'||x=='M'||x=='O'||x=='T'||x=='U'||x=='V'||x=='W'||x=='X'||x=='Y') return false;
 8     return true;
 9 }
10 int main()
11 {
12     cin>>T;
13     while (T--)
14     {
15         cin>>s;
16         bool check=true;
17         for (int i=0;i<s.length();i++) if (deal(s[i])) check=false;
18         for (int i=0;i<s.length();i++) if (s[i]!=s[s.length()-i-1]) check=false;
19         if (check) cout << "yes" << endl; else cout << "no" << endl;
20     }
21     return 0;
22 }

Problem I:

这个题首先把符合条件的字母搞出来,然后我们枚举回文的中间点,往两侧扩展就行了。

然而回文串有奇数长度,有偶数长度不太好处理。

没关系,我们在每相邻的两个字母之间加一个"#"(任何从未出现的字符都可以),然后扫一下就行了。

(其实这道题最长回文子串可以Manacher做啊,O(n)就够了,然而并不需要QWQ。。。)

时间复杂度O(n^2),代码如下:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int T;
 4 string s,ss;
 5 bool deal(char x)
 6 {
 7     if (x=='A'||x=='H'||x=='I'||x=='M'||x=='O'||x=='T'||x=='U'||x=='V'||x=='W'||x=='X'||x=='Y') return false;
 8     if (x=='#') return false;
 9     return true;
10 }
11 int main()
12 {
13     cin>>T;
14     while (T--)
15     {
16         cin>>ss;
17         int n=ss.length();
18         s.clear();
19         s+="#";
20         for (int i=0;i<n;i++)
21         {
22             s+=ss[i];
23             s+="#";
24         }
25         n=s.length();
26         int ans=0;
27         for (int i=0;i<n;i++)
28         {
29             int now=0,tot=0;
30             while (i-now-1>=0&&i+now+1<n&&s[i-now-1]==s[i+now+1]&&(!deal(s[i-now-1]))) ++now;
31             for (int j=i-now;j<=i+now;j++) if (s[j]!='#') ++tot;
32             if (tot>ans&&(!deal(s[i]))) ans=tot;
33         }
34         cout << ans << endl;
35     }
36     return 0;
37 }

Problem J:

看到这道题题目名字里面有个"physics"的时候吓坏我了一直不敢开,结果点进去一看。。。

初中老师说过~~~弓形面积=扇形面积-三角形面积,

扇形面积会不会呀~

三角形面积会不会呀~

编程会不会呀(逃。。。)

时间复杂度O(1),代码如下:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int read()
 4 {
 5     int x=0,f=1;char ch=getchar();
 6     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
 7     while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
 8     return x*f;
 9 }
10 int T,L,A;
11 double ans;
12 int main()
13 {
14     T=read();
15     while (T--)
16     {
17         L=read(),A=read();
18         ans=(double)A/360*L*L*M_PI;
19         ans-=(double)0.5*L*L*sin((double)A/180*M_PI);
20         printf("%.6lf\n",ans);
21     }
22     return 0;
23 }

Problem K:

我们先暴力扫描出这个集合,然后暴力一下就好了。

时间复杂度O(n),代码如下:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int read()
 4 {
 5     int x=0,f=1;char ch=getchar();
 6     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
 7     while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
 8     return x*f;
 9 }
10 int T,a,b,n;
11 int cnt[150];
12 void deal(int n)
13 {
14     int t[15];
15     memset(t,0,sizeof(t));
16     while (n>0)
17     {
18         ++t[n%10];
19         n=n/10;
20     }
21     int ans=0;
22     for (int i=0;i<=9;i++) ans=max(ans,t[i]);
23     for (int i=0;i<=9;i++) if (t[i]==ans) ++cnt[i];
24 }
25 int main()
26 {
27     T=read();
28     while (T--)
29     {
30         memset(cnt,0,sizeof(cnt));
31         a=read(),b=read(),n=read();
32         for (int i=1;1LL*i*i*a+1LL*b*i<=n;i++)
33             deal(1LL*i*i*a+1LL*b*i);
34         int ans=0;
35         for (int i=0;i<=9;i++) if (cnt[i]>cnt[ans]) ans=i;
36         if (a+b>n) ans=-1;
37         cout << ans << endl;
38     }
39     return 0;
40 }

Problem M:

噩梦的一题。。。

我先写了个二分。。。然后我用的是cin。。。惨遭卡常。。。

于是写了个hash。。。惨遭卡常。。。

然后cin改成了scanf。。。WA了。。。

hash写跪了。。。终于过了。。。

时间复杂度O(n),代码如下:

 1 #include <bits/stdc++.h>
 2 #define modp 100000007
 3 using namespace std;
 4 int read()
 5 {
 6     int x=0,f=1;char ch=getchar();
 7     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
 8     while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
 9     return x*f;
10 }
11 int T,c,n;
12 string s1;
13 double s2;
14 map<int,double> mp;
15 double a;
16 string r;
17 int hash(string &s)
18 {
19     long long ans=0,now=1;
20     for (int i=0;i<s.length();i++)
21     {
22         ans=(107LL*ans+1LL*now*(s[i]-'A'+1))%modp;
23         now=(17LL*now)%modp;
24     }
25     return ans%modp;
26 }
27 int main()
28 {
29     //freopen("M.in","r",stdin);
30     //freopen("M.out","w",stdout);
31     T=read();
32     while (T--)
33     {
34         c=read(),n=read();
35         mp.clear();
36         for (int i=1;i<=c;i++)
37         {
38             char ch=getchar();
39             while ((ch<'a'||ch>'z')&&(ch<'A'||ch>'Z')) ch=getchar();
40             long long ans=0,now=1;
41             while (ch!=' ')
42             {
43                 ans=(107LL*ans+1LL*now*(ch-'A'+1))%modp;
44                 now=(17LL*now)%modp;
45                 ch=getchar();
46             }
47             scanf("%lf",&s2);
48             mp[ans%modp]=s2;
49         }
50         r="JD";
51         mp[hash(r)]=1.0;
52         double anss=0.0;
53         for (int i=1;i<=n;i++)
54         {
55             scanf("%lf",&a);
56             char ch=getchar();
57             while ((ch<'a'||ch>'z')&&(ch<'A'||ch>'Z')) ch=getchar();
58             long long ans=0,now=1;
59             while (ch!='\n')
60             {
61                 ans=(107LL*ans+1LL*now*(ch-'A'+1))%modp;
62                 now=(17LL*now)%modp;
63                 ch=getchar();
64             }
65             anss+=a*mp[ans%modp];
66         }
67         printf("%.6lf\n",anss);
68     }
69     return 0;
70 }

写完啦~撒花~

转载于:https://www.cnblogs.com/Tommyr7/p/6743314.html

2017 ACM Arabella Collegiate Programming Contest(solved 11/13)相关推荐

  1. 2017 ACM Arabella Collegiate Programming Contest(solved 9/13, complex 12/13)

    A.Sherlock Bones 题意: 给出长度为n的01串,问f(i,j)=f(j,k),(i<j<k)的i,j,k取值种数.其中f(i,j)表示[i,j]内1的个数, 且s[j]必须 ...

  2. 【容斥】2017 ACM Arabella Collegiate Programming Contest

    比赛连接 G. Snake Rana Old Macdonald wants to build a new hen house for his hens. He buys a new rectangu ...

  3. 2017 ACM Arabella Collegiate Programming Contest div2的题,部分题目写个题解

    F. Monkeying Around   维护点在多少个线段上 http://codeforces.com/gym/101350/problem/F 题意:有m个笑话,每个笑话的区间是[L, R], ...

  4. 2017 ACM Arabella Collegiate Programming Contest G. Snake Rana GYM101350G

    先算一下总的子矩阵个数 总共最多只有20个点 状压一下然后枚举 容斥一下 把求出来的答案减去包含1个点的子矩阵再加上包含2个点的减去3个点的-- #include <iostream> # ...

  5. 2017 ACM Arabella Collegiate Programming Contest

    Gym101350A. Sherlock Bones 题目大意: 给定一个长度为 \(n\) 的 \(01\) 序列 \(\{s_n\}\),定义 \(F(i, j)\) 表示序列第 \(i\) 项到 ...

  6. 2017 ACM Arabella Collegiate Programming Contest E. Competitive Seagulls GYM101350E

    博弈经典套路 考虑把可选择的操作变成2个相同的 然后跟着对手操作 为奇数的时候选一个奇数把两边留出相同长度的白色 为偶数的时候选一个2把两边留出相同长度的白色 那么只有2 和 3 是不可以的 int ...

  7. 2017 ACM Arabella Collegiate Programming Contest A. Sherlock Bones GYM101350A

    把问题转换为求区间内1为奇数的区间有多少个 那么直接记录从1开始为奇数和偶数的区间有多少就算出这个了 但是有不合法的就是只有1个1的区间 所以再减一下 重复的再加回来 #include <ios ...

  8. 2017 ACM Arabella Collegiate Programming Contest F. Monkeying Around GYM101350F

    对单个点考虑 实际上每个点的结果只被最后的那种操作影响 那么处理一下每个点对应的最后一个操作种类 然后对每个种类都和对应的点都检查一下是否被操作了2次 转化成n个点 m个区间 多少点被覆盖>=2 ...

  9. 脑洞 博弈 E. Competitive Seagulls 2017 ACM Arabella Collegiate Programming Contest

    题目链接:http://codeforces.com/gym/101350/problem/E 题目大意:给你一个长度为n的方格,方格上面都被染色成了白色.每次染色都是选择白色的,假设目前选择的这块白 ...

最新文章

  1. ajax frameworks(转贴)
  2. 一道算法题,求更好的解法
  3. JUC包中的分而治之策略-为提高性能而生
  4. js中window.location.href,location.href,parent.location.href,top.location.href的用法
  5. RedHat 6.5中建立Raid5卷(软件磁盘阵列) ;并且对Raid5卷做磁盘配额
  6. python机械编程_机器学习编程作业3——多类分类(Python版)
  7. (并查集)Find them, Catch them
  8. 【架构师面试题库1】—etcd高可用集群搭建
  9. piv图像处理文献综述_图像处理文献综述
  10. C++面试题-指针-指针与指针的引用
  11. django 与 mysql 勾结指南
  12. PHP User Agent
  13. 中国大学MOOC C语言程序设计(大连理工大学) 课后编程题 第五周题解(个人向仅供参考)
  14. 海康威视2022 校招/社招/实习 内推WHM8BQ
  15. arcgis之合并碎小图斑到相邻大块图斑
  16. Spring Boot修改启动神图
  17. 《重新定义团队》读书笔记及阅读感想2600字
  18. 软考考点笔记之松驰时间的计算
  19. ctf crypto writeup
  20. 《深度思维》思维导图读书笔记,精华呈现!

热门文章

  1. 简单教学管理系统画E-R关系图
  2. 用这9个问题来审视自己
  3. /proc 文件系统中的文件及内容介绍
  4. 自制Win 10 Enterprise G版和Win 10 Enterprise GN版镜像
  5. 阿里云docker安装nginx和tomcat
  6. 黑马程序员Java零基础视频教程(2022最新Java)B站视频学习笔记-Day15-阶段项目(拼图小游戏)(上篇)
  7. 什么是uni-app呀?
  8. java中的匿名内部类总结
  9. “共享汽车”探索城市交通建设新模式
  10. uniapp中使用uview组件u-icon 编辑到微信小程序样式问题