正睿多校联盟训练Week6

并没有参加

Problem A.阿瓦分蛋糕
输入文件: cake.in
输出文件: cake.out
时间限制: 1 second
空间限制: 512 megabytes
阿瓦为了庆祝自己自己成长为了一只可爱的小猫,决定提前过生日!
她觉得,在这一年当中帮助过他最多的就是阿卡和烤乐滋了,于是决定这次只请阿卡和烤乐滋两个人吃蛋糕。
阿瓦买了一个 n × m 的蛋糕,她打算分给三个人吃,同时她切蛋糕的时候为了美观,只会在整块的蛋糕上一
划到底。也就是说,她如果在蛋糕上切了一刀,那么这一刀的起点和终点一定在蛋糕的边界上。同时这一刀切下去
的痕迹一定是平行于蛋糕的某条边界的线段,阿瓦认为这样才比较整齐。很容易看出,这样一来阿瓦一定会将整个
蛋糕分成三个长方形。另外值得注意的是,当你切完了一刀之后,蛋糕自动一分为二,你的下一刀的起点或终点就
可以在新产生的边界上了。
阿瓦希望分给三个人的蛋糕面积尽量平均,也就是三个人当中,分到的最大面积与最小面积之差最小。她希望
你来替她求出那个最小的面积差。
Input
一行两个数 n- m。意义如题面中所述。
Output
一行一个数,表示最大面积与最小面积之差。
Example

cake.in cake.out
3 3 0

Constraints
对于 30% 的数据, n, m ≤ 10。
对于 70% 的数据, n, m ≤ 3000 。
对于 100% 的数据, n, m ≤ 1e5。

看一看这道题应该是乱搞。“有一万种方法能过O(1)。"

当然如果蛋糕面积为3的倍数,直接输出0。

题解里给出了一种“O(n)”的做法,即枚举第一次切得位置,那么第二次一定是均分。

然而写完发现理解题意错了。30分。

事实上蛋糕的这个矩形本身就被分成了有限个1x1的小矩形。我们只能从“这种边界”来进行切割。

枚举两次。纵着切和横着切。如果只枚举一次,那么70分。

在各自枚举纵着切和横着切的时候还要枚举第二刀是顺着第一刀的方向切还是垂直第一刀方向切。QAQ。

考虑全面,就不是难题了。QAQ。注意开long long。

code

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 ll n,m;
 5 ll maxer,miner;
 6 ll a,b,c;
 7 ll ans=0x7f7f7f7f;
 8 int main()
 9 {
10     scanf("%lld%lld",&n,&m);
11     if(n*m%3==0)
12     {
13         printf("0\n");
14         return 0;
15     }
16     for(ll i=1;i<=n;i++)
17     {
18         a=(n-i)*m;
19         b=(i>>1)*m;
20         c=i*m-b;
21         maxer=max(max(a,b),c);
22         miner=min(min(a,b),c);
23         ans=min(ans,maxer-miner);
24         b=(m>>1)*i;
25         c=i*m-b;
26         maxer=max(max(a,b),c);
27         miner=min(min(a,b),c);
28         ans=min(ans,maxer-miner);
29     }
30     for(ll i=1;i<=m;i++)
31     {
32         a=(m-i)*n;
33         b=(i>>1)*n;
34         c=i*n-b;
35         maxer=max(max(a,b),c);
36         miner=min(min(a,b),c);
37         ans=min(ans,maxer-miner);
38         b=(n>>1)*i;
39         c=i*n-b;
40         maxer=max(max(a,b),c);
41         miner=min(min(a,b),c);
42         ans=min(ans,maxer-miner);
43     }
44     printf("%lld",ans);
45     return 0;
46 }

Problem B.幻想机器人
输入文件: robot.in
输出文件: robot.out
时间限制: 1 second
空间限制: 512 megabytes
幻想世界科技中心研发出了一种机器人,这种机器人的主要作用是清扫地面。但由于性能还不够稳定,所以它
正常工作的时间不是连续的。
更具体地说,我们可以把幻想世界的地面抽象成一个 n m 列的网格,这个机器人刚开始在科技中心的位置
(x, y),即第 x 行第 y 列,我们把左上角定为第一行第一列。初始时整个网格除了科技中心的位置都是未清扫过的,
科技中心由于测试了多遍机器人的功能非常洁净不需要清扫。
接下来,人们可以给机器人下达一系列命令,但每个命令都是L(左)R(右)U(上)D(下)之
一。表示让机器人往指定的方向移动一格。如果当前格子还能够朝指定方向移动一格,则移动,如果在指定方向已
到达边界,则不移动,并输出一行"AWaDa!"(不包含引号)。
机器人性能不够稳定,它每 K 个指令后清扫一遍它所在的格子。也就是说,第 K、 2K、 3K 个指令后它所
在的格子都会被清扫一遍。注意,不移动位置的指令也算作一个指令。另外,每清扫到一个之前清扫过的格子,输
出一行"AKTang!"(不包含引号)。
最后,大家最关心的还是地面被清扫得怎么样,请你最后再输出一个数,表示未被清扫过的地面格子数。
Input
第一行六个数 n-m- K- len- x- y。意义如题面中所述。 len 表示指令的长度。
第二行一个长度为 len 的字符串,每个字符都是L,R,U,D之一,依次表示每个指令。
Output
对于无法移动的情况,输出一行"AWaDa!"。对于清扫过重复格子的情况,输出一行"AKTang!"。最后输出一行
一个数表示未被清扫过的格子数。
注意输出要按照时间顺序输出。

乍一看还以为是dfs,其实是水模拟。但是很难满分啊QAQ。

读题,明确:题目有两种操作,移动,清扫。清扫仅在第k,2k...步操作后进行。(开始读题这理解错了QAQ。

另外,数据有点不友好,我们没法开到1e9的数组来记录有没有被清扫过。还好我们有伟大的stl!

这里用到了map,建立一个矩阵中第几个格(longlong) 到这个格是否走过的映射。

一个矩阵中第几个格用坐标如何表示可以现场用坐标模拟一下。QAQ。

细节:起点肯定是被扫过的,起点的map设为1。但是起点也不一定是1啊,开始写成cnt[1]=1...

代码中mul()函数是64位大整数乘法,亲测用不用时间差别不大。QAQ。

code

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cmath>
 4 #include<map>
 5
 6 using namespace std;
 7
 8 typedef long long ll;
 9 int len;
10 ll n,m,k,x,y,fin;
11 map<ll,bool> cnt;
12
13 ll mul(ll a,ll b)
14 {
15     ll ans=0;
16     while(b)
17     {
18         if(b&1) ans=ans+a;
19         b>>=1;
20         a=a*2;
21     }
22     return ans;
23 }
24
25 int main()
26 {
27     scanf("%lld%lld%lld%d%lld%lld",&n,&m,&k,&len,&x,&y);
28     char ch=getchar();cnt[m*(x-1)+y]=1;//不要想成特殊,一般化 QAQ
29     for(ll i=1;i<=len;i++)
30     {//移动和清扫是不一样的 QAQ  明确操作
31         scanf("%c",&ch);
32         if(ch==‘U‘)
33         {
34             if(x==1) printf("AWaDa!\n");
35             else x--;
36         }
37         if(ch==‘L‘)
38         {
39             if(y==1) printf("AWaDa!\n");
40             else y--;
41         }
42         if(ch==‘R‘)
43         {
44             if(y==m) printf("AWaDa!\n");
45             else y++;
46         }
47         if(ch==‘D‘)
48         {
49             if(x==n) printf("AWaDa!\n");
50             else x++;
51         }
52         if(i%k==0)
53         {
54             if(cnt[m*(x-1)+y]) printf("AKTang!\n");
55             else cnt[m*(x-1)+y]=1,fin++;
56         }
57     }
58     printf("%lld\n",mul(m,n)-fin-1);
59     //用不用mul()差别不大 QAQ
60     return 0;
61 }

可以用并查集求出联通块个数。最后答案就是m^联通块个数(根据加法原理)。

并查集+快速幂

code

 1 #include<bits/stdc++.h>
 2
 3 using namespace std;
 4 typedef long long ll;
 5 int n,m,T;
 6 ll ans;
 7 ll moder=998244353;
 8 int fa[200000];
 9
10 int getf(int p)
11 {
12     if(fa[p]==p) return p;
13     else
14     {
15         fa[p]=getf(fa[p]);
16         return fa[p];
17     }
18 }
19
20 void merge(int p,int q)
21 {
22     int pp=getf(p);
23     int qq=getf(q);
24     if(qq!=pp) fa[qq]=pp;
25 }
26
27 ll ksm(ll a,ll b)
28 {
29     ll tot=1;
30     while(b)
31     {
32         if(b&1) tot=tot*a%moder;
33         b>>=1;
34         a=a*a%moder;
35     }
36     return tot%moder;
37 }
38
39 int main()
40 {
41     scanf("%d%d%d",&n,&m,&T);
42     for(int i=1;i<=n;i++) fa[i]=i;
43     for(int i=1;i<=T;i++)
44     {
45         int x=0,y=0;
46         scanf("%d%d",&x,&y);
47         merge(x,y);
48     }
49     for(int i=1;i<=n;i++) if(fa[i]==i) ans++;
50     printf("%lld",ksm(m,ans));
51     return 0;
52  } 

直接上sol好了...另外不能分1,1肯定是没有贡献的。

这题还得打个高精。难受。

code

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 int T;
 5 ll R;
 6 int ans[3000],now[3000];
 7 void mul(int x)
 8 {
 9     memset(now,0,sizeof(now));
10     for(int i=1;i<=ans[0];i++)
11     {
12         now[i]+=ans[i]*x%10;
13         now[i+1]+=ans[i]*x/10;
14         now[i+1]+=now[i]/10;
15         now[i]%=10;
16     }
17     for(int i=1;i<=ans[0];i++)
18      ans[i]=now[i];
19     if(now[ans[0]+1])
20     {
21         ans[0]++;
22         ans[ans[0]]=now[ans[0]];
23     }
24 }
25 int main()
26 {
27     scanf("%d",&T);
28     for(int i=1;i<=T;i++)
29     {
30         scanf("%lld",&R);
31         ans[0]=ans[1]=1;
32         int tmp=R/3;
33         if(R%3==0)
34         {
35             for(int j=1;j<=tmp;j++)
36              mul(3);
37         }
38         if(R%3==1)
39         {
40             for(int j=1;j<=tmp-1;j++)
41              mul(3);
42             mul(4);
43         }
44         if(R%3==2)
45         {
46             for(int j=1;j<=tmp;j++)
47              mul(3);
48             mul(2);
49         }
50         for(int i=ans[0];i>=1;i--)
51          printf("%d",ans[i]);
52         printf("\n");
53         memset(ans,0,sizeof(ans));
54     }
55     return 0;
56  } 

原文地址:https://www.cnblogs.com/nopartyfoucaodong/p/9208212.html

时间: 2024-08-30 11:46:24

正睿多校联盟训练Week6的相关文章

正睿多校联盟训练Week5

T1 Problem A. 阿瓦的海报输入文件: poster.in输出文件: poster.out时间限制: 1 second空间限制: 512 megabytes阿瓦为了宣传她的影展,准备画一张海报张贴在幻想镇的各个角落.她为了让海报引人注目,已经在图案.背景和排版上费了很大的工夫.但这时她接到一个来自印刷厂的通知:印刷厂的纸不够了,本来答应给阿瓦定做的海报不能达到预期的尺寸.印刷厂表示,剩下的纸最多能够承担每张海报的面积为 S.而阿瓦认为,海报的面积应当是越大越好,所以阿瓦决定,就将每张海

HDU 5371 (2015多校联合训练赛第七场1003)Hotaru&#39;s problem(manacher+二分/枚举)

HDU 5371 题意: 定义一个序列为N序列:这个序列按分作三部分,第一部分与第三部分相同,第一部分与第二部分对称. 现在给你一个长为n(n<10^5)的序列,求出该序列中N序列的最大长度. 思路: 来自官方题解:修正了一些题解错别字(误 先用求回文串的Manacher算法,求出以第i个点为中心的回文串长度,记录到数组p中 要满足题目所要求的内容,需要使得两个相邻的回文串,共享中间的一部分,也就是说,左边的回文串长度的一半,要大于等于共享部分的长度,右边回文串也是一样. 因为我们已经记录下来以

HDU 5371 (2015多校联合训练赛第七场1003)Hotaru&amp;#39;s problem(manacher+二分/枚举)

pid=5371">HDU 5371 题意: 定义一个序列为N序列:这个序列按分作三部分,第一部分与第三部分同样,第一部分与第二部分对称. 如今给你一个长为n(n<10^5)的序列,求出该序列中N序列的最大长度. 思路: 来自官方题解:修正了一些题解错别字(误 先用求回文串的Manacher算法.求出以第i个点为中心的回文串长度.记录到数组p中 要满足题目所要求的内容.须要使得两个相邻的回文串,共享中间的一部分,也就是说.左边的回文串长度的一半,要大于等于共享部分的长度,右边回文串也

2014多校联合训练第一场(组队训练)

这是我.potaty.lmz第二次训练,毕竟经验不足,加上水平不够,导致我们各种被碾压. A - Couple doubi: 这道题是道比较水的数论.但我们都没想出来要怎么做.后来是potaty提议打个表看看,然后lmz打出表后发现了规律.我还没细看,待研究后再补全. D - Task: 这道题一看就知道是个贪心(现在只要是有deadline的题我都觉得是贪心了).虽然想出来了,但还是不会严格证明为什么只要取满足task的且y最小(y相等时x最小)的machine就行了. 我的做法是把所有mac

9.22 正睿提高4

目录 2018.9.22 正睿提高5 A 数组计数(DP) B 旅行(思路) C 进化(思路 二进制拆分) 考试代码 B C 2018.9.22 正睿提高5 时间:3.5h 期望得分:100+80+30 实际得分:100+80+30 比赛链接 T2一直以为类似某道虚树题(SDOI2015)..到最后只想写暴力(写了暴力也该想到了啊 但是已经在划水了). A 数组计数(DP) 题目链接 DP.前缀和优化一下就行了. 刚开始滚动数组又少清空了mmp.. #include <cstdio> #inc

正睿OI国庆DAY2:图论专题

正睿OI国庆DAY2:图论专题 dfs/例题 判断无向图之间是否存在至少三条点不相交的简单路径 一个想法是最大流(后来说可以做,但是是多项式时间做法 旁边GavinZheng神仙在谈最小生成树 陈主力说做法是dfs 首先两个点一定在点双联通分量里 点双是简单环,只有两条,不存在 猜测其他情况存在三条 双联通分量分解 输出情况可以用dfs树判,讨论非树边覆盖情况 内包含 下面分叉连到上面 相交 输出点即可 BFS/例题 BFS树没有跳跃边 计数/动态规划有用吧 树上bfs序好像可以判断距离? 边权

正睿OI DAY3 杂题选讲

正睿OI DAY3 杂题选讲 CodeChef MSTONES n个点,可以构造7条直线使得每个点都在直线上,找到一条直线使得上面的点最多 随机化算法,check到答案的概率为\(1/49\) \(n\leq k^2\) 暴力 \(n\geq k^2\),找点x,求直线l经过x,且点数最多,点数\(\geq k+1\),递归,否则再找一个 One Point Nine Nine 现在平面上有\(n\)个点,已知有一个常数\(D\). 任意两点的距离要么\(\leq D\),要么\(\geq 1.

2015年多校联合训练第四场(Problem Killer)hdu5328

题意: 求最大等差或等比数列的长度 思路: 开始用二分,WA暴了,后来发现我用的等差数列公式有问题 (a[i]+a[j])*(j-i+1)/2,等差数列一定满足这个公式,但满足这个公式的不一定是等差数列,我sb了..... 还有就算等比数列a[i+1]/a[i] == a[i]/a[i-1],也是sb了,这个会引起精度丢失,应该a[i]^2 = a[i-1]*a[i+1]; --. 正解应该是不管等差还是等比数列,如果a,b,c是等差,b,c,d是等差,那么a,b,c,d肯定是等差 然后扫一遍就

校队训练赛,同时也是HDU4497(数论:素数分解+组合数学)

一.题目 http://acm.hdu.edu.cn/showproblem.php?pid=4497 二.思路 将满足条件的一组x,z,y都除以G,得到x‘,y',z',满足条件gcd(x',y',x') = 1,同时lcm(x',y',x') = G/L.特判,当G%L != 0 时,无解.然后素数分解G/L,假设G/L = p1^t1 * p2^t2 *````* pn^tn.满足上面条件的x,y,z一定为这样的形式.x' = p1^i1 * p2^i2 *```* pn^in.y' =