【训练赛】zcmu2959--1986--1980--1907--1916--3037

目录

  1. zcmu-2959 : Amity Assessment(思维&&字符串)
  2. zcmu-1986 : 周期串plus(思维)
  3. zcmu-1980 : 不存在的泳池(思维&&最大公因数)
  4. zcmu-1907 : k倍区间(思维&&前缀和优化)
  5. zcmu-1916 : 当然是选择原谅你
  6. zcmu-3037 : Block Towers(思维&&贪心)

2959  B: Amity Assessment(思维&&字符串)

Time Limit: 2 Sec  Memory Limit: 256 MB
Submit: 52  Solved: 18
[Submit][Status][Web Board]

Description

Bessie the cow and her best friend Elsie each received a sliding puzzle on Pi Day. Their puzzles consist of a 2×2 grid and three tiles labeled 'A', 'B', and 'C'. The three tiles sit on top of the grid, leaving one grid cell empty. To make a move, Bessie or Elsie can slide a tile adjacent to the empty cell into the empty cell as shown below:

In order to determine if they are truly Best Friends For Life (BFFLs), Bessie and Elsie would like to know if there exists a sequence of moves that takes their puzzles to the same configuration (moves can be performed in both puzzles). Two puzzles are considered to be in the same configuration if each tile is on top of the same grid cell in both puzzles. Since the tiles are labeled with letters, rotations and reflections are not allowed.

Input

 The first two lines of the input consist of a 2×2 grid describing the initial configuration of Bessie's puzzle. The next two lines contain a 2×2 grid describing the initial configuration of Elsie's puzzle. The positions of the tiles are labeled 'A', 'B', and 'C', while the empty cell is labeled 'X'. It's guaranteed that both puzzles contain exactly one tile with each letter and exactly one empty position.

Output

 Output "YES"(without quotes) if the puzzles can reach the same configuration (and Bessie and Elsie are truly BFFLs). Otherwise, print "NO" (without quotes).

Sample Input

AB XC XB AC

Sample Output

YES

HINT

The solution to the sample is described by the image. All Bessie needs to do is slide her 'A' tile down.

【分析】因为只有4个格子,一个空位,所以其实所有的字母只能按一个方向转。假设都是顺时针转的话,原图是ABCX,转之后的是XBCA,如果可以转到,那么其中一个串必然是另一个串的子串。注意去掉X后再比较。

【代码】

#include
using namespace std;
int main()
{
	string s1,s2;
	while(cin>>s1)
	{
		string str11,str22;
		cin>>s2;
		reverse(s2.begin(),s2.end());
		string str1=s1+s2;
		int len=str1.length();
		for(int i=0;i>s3>>s4;
		reverse(s4.begin(),s4.end());
		string str2=s3+s4+s3+s4;
		int len2=str2.length();
		for(int i=0;i

1986 C: 周期串plus(思维)

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 223  Solved: 106
[Submit][Status][Web Board]

Description

如果一个字符串可以由某个长度为k的字符串重复多次得到,我们说该串以k为周期。例如abcabcabcabc以3为周期(当然他也以6,12为周期)。输入一个长度不超过100000的串,输出他的最小周期。

Input

多组测试数据,每组仅一行为一个仅有大写字母组成的字符串。

Output

对于每组数据输出该字符串的最小周期。

Sample Input

HOHO

Sample Output

2

【分析】最小周期,则可从小到大枚举各个周期,只要有符合的就输出。

【代码】

#include
using namespace std;
const int maxn=1e5+5;
char s[maxn];
int main()
{
    while(~scanf("%s",s))
    {
        int len=strlen(s);
        int flag=0;
        for(int i=1;i<=len;i++)
        {
            if(len%i==0) 
            {
                flag=1;
                for(int j=i;j

1980 D: 不存在的泳池(思维&&最大公因数)

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 332  Solved: 141
[Submit][Status][Web Board]

Description

小w是云南中医学院的同学,有一天他看到了学校的百度百科介绍:
截止到2014年5月,云南中医学院图书馆纸本藏书74.8457万册,纸质期刊388种,馆藏线装古籍图书1.8万册,电子资源总量35TB,拥有中、外文数据库25个,电子图书29.5万册(镜像)、包库130万册。古籍线装图书1.8万余册,有39种列为本馆珍善本,如《彻滕八编》、《赵氏医贯》等明清版本、台湾文渊阁版本《四库全书》,按《全国古籍善本书总目》分类表(即:经·史·子·集四部分类)部编列、上架、供读者使用。
显然学校图书馆的占地面积非常大,于是他开始想象.....如果他有一个跟图书馆一样大的游泳池?!
如果有一个那么大的游泳池,他就可以邀请女神一起去游泳...
如果有一个那么大的游泳池,他还可以划开一半出租,收取门票费赚钱...这样等赚了一些钱之后,就招一些游泳教练来,然后对外招生,招收学生继续赚更多的钱!
如果有一个那么大的游泳池,他还能把泳池里的水全部放光...开一个吕子乔心目中最大最棒的泳池派对!
.......
等有了更多的钱,就可以在第一个泳池旁边再建一个一样大的泳池......
小w一边流口水一边想自己的未来,一想到女神看到自己事业有成,靠一个游泳池白手起家发家致富,对自己投怀送抱,高兴的根本合不拢嘴。
这时候旁边的小q作为小w的室友,随口提了一句:“这么大的泳池,你怎么换水?”
显然小w是个有原则的人,他不会让自己的泳池像不法商家一样不换水,用不干净的水给别人使用或者给自己使用。
小w百度了之后发现...淘宝里有一家店卖一种一次性抽水机,这种一次性抽水机很神奇,它有两个按钮:
1.如果泳池里的水(立方米)是3的倍数,那么可以按第一个按钮让它抽走泳池里三分之二的水
2.如果泳池里的水(立方米)是2的倍数,那么可以按第二个按钮让它抽走泳池里二分之一的水
小w虽然是个有原则的人,但是作为一个商人,他需要节省钱...而且他现在有两个泳池....但是显然这种抽水机不能把水抽光,水越少,性价比就越低。
但是两个泳池建在一起,如果两个泳池的水面不一样高,那么小w会很不开心,所以他想用这种抽水机,把两个泳池里的水抽成一样多。然后再考虑别的....当然在保证能把两个泳池里的水抽成一样多的情况下..他希望花的钱最少...
(不管了!好看最重要,好看才能吸引顾客啊!先好看!再考虑怎么换水吧)

Input

多组测试数据,给出A,B表示两个泳池当前的水量(立方米)

(1<=A,B<=10^9)

Output

每组测试数据输出一个整数表示至少需要买多少个一次性抽水机,若买多少个都不能让泳池的水相等,则输出"-1"

Sample Input

5 20

14 8

6 6

Sample Output

2

-1

0

HINT

 显然这一切都是他的YY,他怎么可能会有游泳池???

【分析】求最大公因数,如果两个数除以他们的最大公因数后可以同时等于同一个数就存在,否则不存在。

【代码】

#include
using namespace std;
int gcd(int x,int y)
{
    return y==0?x:gcd(y,x%y);
}
int main()
{
    int a,b;
    while(~scanf("%d%d",&a,&b))
    {
        int x=gcd(a,b),flag=1,cnt=0;
        a/=x,b/=x;
        if(a%2==0)
        {
            while(a%2==0)
            {
                a/=2;
                cnt++;
            }
        }
        if(a%3==0)
        {
            while(a%3==0)
            {
                a/=3;
                cnt++;
            }
        }
        if(b%2==0)
        {
            while(b%2==0)
            {
                b/=2;
                cnt++;
            }
        }
        if(b%3==0)
        {
            while(b%3==0)
            {
                b/=3;
                cnt++;
            }
        }
        if(a==b)printf("%d\n",cnt);
        else printf("-1\n");
    }
    return 0;
}

1907 E: k倍区间(思维&&前缀和优化)

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 146  Solved: 44
[Submit][Status][Web Board]

Description

给定一个长度为N的数列,A1, A2, ... AN,如果其中一段连续的子序列Ai, Ai+1, ... Aj(i <= j)之和是K的倍数,我们就称这个区间[i, j]是K倍区间。

你能求出数列中总共有多少个K倍区间吗?

Input

每个数据包含多组输入数据

第一行包含两个整数N和K。(1 <= N, K <= 100000)
以下N行每行包含一个整数Ai。(1 <= Ai <= 100000)

Output

输出一个整数,代表K倍区间的数目。

Sample Input

5 2
1
2
3
4
5

Sample Output

6

【分析】普通方法做的话肯定会超时,所以要用到前缀和。然鹅,,普通前缀和还是会超时,所以,,优化。

              如果两个数对同一个数a取余的结果相同,那么这两个数相减的结果一定能整除a。

              所以,本题,如果两个区间里的数的和除以k同余,那么这两个区间相减之后便能整除k了٩(๑❛ᴗ❛๑)۶

统计前缀和:
sum[1] = a1;
sum[2] = a1+a2;
sum[n] = a1+a2+…+an;
对于任意一段区间[l,r]的和就是sum[r]-sum[l-1]
(sum[r]-sum[l-1])%k :使得该区间%k后≤k(可以等于0。等于0即表示正好是k的倍数)然后统计同余区间数即可。

【代码】

#include
using namespace std;
const int maxn=1e5+5;
int sum[maxn],num[maxn];
int main()
{
    int n,k;
    while(~scanf("%d%d",&n,&k))
    {
        int cnt=0;
        memset(num,0,sizeof(num));
        memset(sum,0,sizeof(sum));
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&num[i]);
            num[i]=(num[i]+num[i-1])%k;
            if(num[i]==0)cnt++;//统计序列中本身可以整除k的个数
        }
        for(int i=1;i<=n;i++)
        {
             cnt+=sum[num[i]];//注意顺序
             sum[num[i]]++;
        }
        printf("%d\n",cnt);
    }
    return 0;
}

1916 F: 当然是选择原谅你

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 161  Solved: 103
[Submit][Status][Web Board]

Description

        最近HX无所事事,他的脑海里出现了一个想法。这个游戏盘的大小是n*m。首先,硬币放在右上角(1,m)。 每次有人可以将硬币移动到左边,下面或左下方的空白处。不能移动的人将失去游戏。 HX只能无聊到找XH玩了。游戏总是从HX开始。 如果两人都玩得很好,谁能赢得比赛呢?

Input

多组输入,直到输入0 0结束。

输入n和m(1 ≤ n ≤ 10^6)表示游戏盘的长与宽。

Output

如果HX赢则输出H,否则输出X。

Sample Input

5 3

5 4

0 0

Sample Output

X

H

【分析】简单博弈。因为输出只有两种,所以其实把四种情况列举出来就可以了。即讨论棋盘长和宽的奇偶。

【代码】

#include
using namespace std;
const int maxn=1e6+5;
int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m)&&n&&m)
    {
        if(n%2!=0&&m%2!=0)
            printf("X\n");
        else printf("H\n");
    }
    return 0;
}

3037 H: Block Towers(思维&&贪心)

Time Limit: 2 Sec  Memory Limit: 256 MB
Submit: 48  Solved: 20
[Submit][Status][Web Board]

Description

Students in a class are making towers of blocks. Each student makes a (non-zero) tower by stacking pieces lengthwise on top of each other. n of the students use pieces made of two blocks and m of the students use pieces made of three blocks.

The students don’t want to use too many blocks, but they also want to be unique, so no two students’ towers may contain the same number of blocks. Find the minimum height necessary for the tallest of the students' towers.

Input

 The first line of the input contains two space-separated integers n and m (0≤n,m≤1000000, n+m>0)− the number of students using two-block pieces and the number of students using three-block pieces, respectively.

Output

 Print a single integer, denoting the minimum possible height of the tallest tower.

Sample Input

1 3

Sample Output

9

HINT

 In the first case, the student using two-block pieces can make a tower of height 4, and the students using three-block pieces can make towers of height 3, 6, and 9 blocks. The tallest tower has a height of 9 blocks.

【分析】

1. 题意:n个人使用高度为2的块堆叠,m个人使用高度为3的块堆叠,求使用最少的块能达到的最大的高度。

2. 思路:贪心算法

//PS:这道题做的时候思路错了,emmm题意理解错了,但是代码A了,就很奇怪。

这道题是要找n+m个人中的能达到的最大高度的最小值。我们要求(m+n)个人中能达到的最大高度的最小值,就要让每个人的高度尽可能小,因为材料无限,高度本可以无限大,但是要尽可能小,并且不能有重复,所以遇到6、12这种数就要讨论一下。材料是不限的。比如:n=4, m=3

n(=4) 2 4 6 8
m(=3) 3 6 9  

由上表,可知6重复了。但是不能有重复值,所以,有一个人的6不能要。所以会有下面两种情况:

n(=4) 2 4 6 8
m(=3) 3 6 9 12(9+3)
n(=4) 2 4 6 8 10(8+2)
m(=3) 3 6 9    

由上两表,可知,7个人能达到的最大高度是12,最小高度是10。所以,最终结果为10;

 【代码】

#include
using namespace std;
int main()
{
    int n, m;
    while(~scanf("%d%d",&n,&m)){
        n*=2, m*=3;
        for(int i=6;i<=min(n,m);i+=6)
        {  //注意这里是+6
            if(n<=m)n+=2;
            else m+=3;
        }
        printf("%d\n", max(n,m));
    }
    return 0;
}

 

你可能感兴趣的:(思维,ZCMU-OJ,ACM刷题册)