洛谷刷题C语言:BAZA、YODA、SPAVANAC、COKOLADA、KINO

记录洛谷刷题C语言qaq


[COCI2016-2017#7] BAZA

题目描述

Mirko 在一家大型的 IT 公司获得了暑期实习的机会。这家公司建造了一个大型数据库,包含 N N N M M M 列,第 i i i 行第 j j j 列上的整数是 A i , j A_{i,j} Ai,j

在他实习的第一天,他收到了 Q Q Q 次询问,每一次询问包含 M M M 个整数 B 1 , B 2 , … , B M B_1,B_2,\dots,B_M B1,B2,,BM。但不幸的是,有些数在传输的过程中丢失了,数据库将它们替换为 − 1 -1 1。Mirko 需要回答数据库中有多少行和询问中的所有数匹配。形式化的说,Mirko 需要回答在范围 [ 1 , N ] [1,N] [1,N] 内有多少个整数 i i i,满足 ∀ j ∈ [ 1 , M ] \forall j\in[1,M] j[1,M] B j = − 1 B_j=-1 Bj=1 B j = A i , j B_j=A_{i,j} Bj=Ai,j。例如,如果 M = 3 M=3 M=3,某一次询问为 − 1   3   2 -1~3~2 1 3 2,那么 Mirko 需要找到所有满足第一列为任意整数,第二列为 3 3 3,第三列为 2 2 2 的行数。

Mirko 毕竟是刚开始实习的新人,因此他希望能够得到你的帮助。现在,请你帮助他回答这些询问!

输入格式

第一行输入两个整数 N , M N,M N,M,分别表示数据库的行数和列数。
随后 N N N 行,每行输入 M M M 个整数,描述这个数据库。
随后一行输入一个整数 Q Q Q,表示询问次数。
随后 Q Q Q 行,每行输入 M M M 个整数,描述一次询问。

输出格式

对于每次询问,输出一行一个整数,表示满足要求的行数。

样例 #1

样例输入 #1

4 3
1 5 2
2 3 4
4 3 2
5 4 6
3
-1 -1 2
-1 3 2
-1 -1 -1

样例输出 #1

2
1
4

样例 #2

样例输入 #2

3 8
6 5 97 99 82 50 95 1
85 62 11 64 94 84 88 19
43 99 11 64 94 84 31 19
3
-1 -1 11 64 94 84 -1 19
-1 -1 -1 99 -1 -1 -1 1
95 -1 -1 -1 -1 80 -1 -1

样例输出 #2

2
1
0

提示

【样例 1 解释】

对于第一次询问,第一行和第三行满足询问中第三列是 2 2 2 的要求。
对于第二次询问,只有第三行满足询问中第二列是 3 3 3,第三列是 2 2 2 的要求。
对于第三次询问,由于并没有对每一列上的数作出要求,因此所有行都满足要求。

【数据范围】

对于所有数据, 1 ⩽ N , M ⩽ 1 0 3 1\leqslant N,M\leqslant 10^3 1N,M103 1 ⩽ Q ⩽ 50 1\leqslant Q\leqslant 50 1Q50 1 ⩽ A i , j ⩽ 1 0 6 1\leqslant A_{i,j}\leqslant 10^6 1Ai,j106 B j = − 1 B_j=-1 Bj=1 1 ⩽ B j ⩽ 1 0 6 1\leqslant B_j\leqslant 10^6 1Bj106

【题目来源】

本题来源自 COCI 2016-2017 CONTEST 7 T1 BAZA,按照原题数据配置,满分 50 50 50 分。

由 Eason_AC 翻译整理提供。

代码如下

#include
#include
#include
#include 


int main()
{
	int n, m;
	scanf("%d%d",&n,&m);
	
	int num[n][m];
	for(int i  = 0;i < n;i++)
	{
		for(int j = 0;j < m;j++)
		{
			scanf("%d",&num[i][j]);
		}
	}
	
	int k;
	scanf("%d",&k);
	
	
	int b[10001];
	while(k--)
	{
		memset(b,0,sizeof(b));
		int sum = 0;
		int a;
		for(int i = 0;i < m;i++)
		{
			scanf("%d",&a);
			if(a != -1)
			{
				for(int j = 0;j < n;j++)
				{
					if(num[j][i] != a)
						b[j] = 1;
				} 
			}
		}
		
	
		for(int j = 0;j < n;j++)
		{
			if(!b[j])
				sum++;
		}
		
		printf("%d\n",sum);
	}
	return 0;	
} 

[COCI2015-2016#4] YODA

题目背景

很久很久以前,在一个遥远的星系里,一个巨大的整数碰撞正在发生。

题目描述

当两个整数碰撞时会发生什么?先将数位较少的数前不断添加前导 0 0 0 直到和数位较高的数的数位数量相同为止。然后,从两个数的最低位开始,每次将两个数的对应数位进行比较,并删去较小的那个数位(如果这两个数位相等则不执行任何操作),不断向高数位执行上述操作,直到最高位为止。此时,将这两个数中没有删去的数位按顺序依次拼接,可以得到两个新数。

例如,对于 456328 456328 456328 284315 284315 284315 这两个数,这两个的碰撞过程如下所示:

4 4 4   5   \sout{~5~}  5  6 6 6 3 3 3 2 2 2 8 8 8
  2   \sout{~2~}  2  8 8 8   4   \sout{~4~}  4  3 3 3   1   \sout{~1~}  1    5   \sout{~5~}  5 

不难看出,碰撞之后得到的两个新数为 46328 46328 46328 83 83 83

现在给定两个数 n , m n,m n,m,请求出这两个数进行碰撞之后分别得到的新数。如果某个数在进行碰撞之后,其数位都已经被删空了,则在输出中输出一行字符串 YODA。具体见『输出格式』部分。

输入格式

第一行输入一个整数 n n n,表示要进行碰撞的第一个数。
第二行输入一个整数 m m m,表示要进行碰撞的第二个数。

输出格式

输出共两行。

第一行中,如果 n n n 的数位已经删空,则输出一个字符串 YODA,否则输出一个整数,表示 n n n 进行碰撞后得到的新数。
第二行中,如果 m m m 的数位已经删空,则输出一个字符串 YODA,否则输出一个整数,表示 m m m 进行碰撞后得到的新数。

样例 #1

样例输入 #1

300
500

样例输出 #1

0
500

样例 #2

样例输入 #2

65743
9651

样例输出 #2

673
95

样例 #3

样例输入 #3

2341
6785

样例输出 #3

YODA
6785

提示

【样例解释 2】

对于样例 2 2 2,这两个数碰撞的过程如下所示:

6 6 6   5   \sout{~5~}  5  7 7 7   4   \sout{~4~}  4  3 3 3
  0   \sout{~0~}  0  9 9 9   6   \sout{~6~}  6  5 5 5   1   \sout{~1~}  1 

因此,碰撞之后得到的两个新数分别是 673 673 673 95 95 95

【数据范围】

对于 30 % 30\% 30% 的数据,保证 n n n m m m 由三位数字组成。
对于所有数据, 1 ⩽ n , m ⩽ 1 0 9 1\leqslant n,m\leqslant 10^9 1n,m109

【题目来源】

本题来源自 COCI 2015-2016 CONTEST 4 T1 YODA,按照原题数据配置,满分 50 50 50 分。

由 Eason_AC 翻译整理提供。

代码如下

#include
#include
#include
#include 

char s1[1001],s2[1001];
int tong1[10],tong2[10];
int ans1=0,ans2=0;
int main()
{
    scanf("%s%s",&s1,&s2);
    int len1=strlen(s1);//第1步,统计长度
    int len2=strlen(s2);
    int len=len1;
    if(len1<len2)//第2步,补上对应数量的0
    {
        for(int i=len1;i>=0;i--)
        {
            s1[i+len2-len1]=s1[i];
        }
        for(int i=0;i<len2-len1;i++)
        {
            s1[i]='0';
        }
        len=len2;
    }
    if(len1>len2)
    {
        for(int i=len2;i>=0;i--)
        {
            s2[i+len1-len2]=s2[i];
        }
        for(int i=0;i<len1-len2;i++)
        {
            s2[i]='0';
        }
        len=len1;
    }
    for(int i=0;i<len;i++)//第3步,进行两个字符串比对,并将删去的字符设上标记
    {
        if(s1[i]<s2[i])
        {
            tong1[i]=1;
            ans1++;
        }
        else if(s1[i]>s2[i])
        {
            tong2[i]=1;
            ans2++;
        }
    }
    if(ans1==len)//第4步,进行特判,如果有其中一个字符串删空了就进行特殊处理
    {
        printf("YODA\n");
        for(int i=0;i<len;i++)
        {
            printf("%c",s2[i]);
        }
        return 0;
    }
    if(ans2==len)
    {
        for(int i=0;i<len;i++)
        {
            printf("%c",s1[i]);
        }
        printf("\nYODA\n");
        return 0;
    }
    int ok=1;
    for(int i=0;i<len;i++)//第5步,处理正常情况,将输出的两个字符串分别删去前导0
    {
        if(tong1[i]==0&&s1[i]=='0')
        {
            tong1[i]=1;
            ans1++;
        }
        else if(tong1[i]==0&&s1[i]!='0')
        {
            ok=0;
            break;
        }
    }
    ok=1;
    for(int i=0;i<len;i++)
    {
        if(tong2[i]==0&&s2[i]=='0')
        {
            tong2[i]=1;
            ans2++;
        }
        else if(tong2[i]==0&&s2[i]!='0')
        {
            ok=0;
            break;
        }
    }
    for(int i=0;i<len;i++)//第6步,根据删除标记进行输出
    {
        if(ans1==len)
        {
            printf("0");
            break;
        }
        if(tong1[i]==0)
        {
            printf("%c",s1[i]);
        }
    }
    printf("\n");
    for(int i=0;i<len;i++)
    {
        if(ans2==len)
        {
            printf("0");
            break;
        }
        if(tong2[i]==0)
        {
            printf("%c",s2[i]);
        }
    }
    return 0;
}

[COCI2009-2010#7] SPAVANAC

题目描述

给定 24 24 24 小时制下的时间 H : M H:M H:M,输出 24 24 24 小时制下比该时间早 45 45 45 分钟对应的时刻。

输入格式

第一行,两个正整数 H , M H,M H,M

输出格式

输出两个整数,表示早 45 45 45 分钟后的时刻。

样例 #1

样例输入 #1

10 10

样例输出 #1

9 25

样例 #2

样例输入 #2

0 30

样例输出 #2

23 45

样例 #3

样例输入 #3

23 40

样例输出 #3

22 55

提示

【数据规模与约定】

  • 对于 100 % 100\% 100% 的数据, 0 ≤ H ≤ 23 0 \le H \le 23 0H23 0 ≤ M ≤ 59 0 \le M \le 59 0M59

【提示与说明】

题目译自 COCI 2009-2010 CONTEST #7 Task 1 SPAVANAC

本题分值按 COCI 原题设置,满分 30 30 30

代码如下

#include
#include
#include
#include 

int main()
{
	int a, b;
	scanf("%d%d",&a,&b);
	
	if(b - 45 < 0)
	{
		a--;
		b = b + 60 - 45;
		if(a - 1 < 0)
		{
			a = 23;
		}
	}
	else if(b - 45 >= 0)
	{
		b = b - 45;
	}
	printf("%d %d\n",a,b);
	return 0;
}

[COCI2009-2010#7] COKOLADA

题目描述

顾客急需大小为 K K K 个单位的巧克力,但现在你只能选择一块大小为 2 2 2 的非负整数幂(即 1 , 2 , 4 , 8 , 16 , ⋯ 1,2,4,8,16,\cdots 1,2,4,8,16,)的巧克力进行购买。

为了满足顾客需求,可以采取切割的方式,将一块大小为 D D D 个单位的巧克力切成两块大小为 D 2 \dfrac{D}{2} 2D 个单位的巧克力。

为了降低成本,你需要求出所需的巧克力大小的最小值和最小切割次数。

输入格式

第一行,一个正整数 K K K,表示顾客所需的巧克力大小。

输出格式

输出两个整数,分别表示巧克力大小的最小值和所系的最少切割次数。

样例 #1

样例输入 #1

6

样例输出 #1

8 2

样例 #2

样例输入 #2

7

样例输出 #2

8 3

样例 #3

样例输入 #3

5

样例输出 #3

8 3

提示

【数据规模与约定】

  • 对于 100 % 100\% 100% 的数据, 1 ≤ K ≤ 1 0 6 1 \le K \le 10^6 1K106

【提示与说明】

题目译自 COCI 2009-2010 CONTEST #7 Task 2 COKOLADA

本题分值按 COCI 原题设置,满分 50 50 50

代码如下

#include
#include
#include
#include 


int k,q=1,s;//切记 q=1
int main()
{
	scanf("%d",&k);
	while(q<k)
		q*=2;
	if(q==k)
		return !printf("%d 0",q);
	else printf("%d ",q);
	while(k>0)
		q/=2,k%=q,s++;
	return !printf("%d",s);
}

[COCI2011-2012#4] KINO

题目描述

电影院的每排有 N N N 个座位。座位分为普通座位( S \texttt S S)和爱心座位( L \texttt L L)。其中,爱心座位总是两两出现。

每排座位的相邻两个座位之间都设有一个杯架(除了两个爱心座位之间外)。特别地,一排座位的两侧也都设有杯架。

现有 N N N 位顾客坐满这 N N N 个座位,求最多有多少人能够使用杯座。

输入格式

第一行,一个整数 N N N

第二行, N N N 个字符 S/L \texttt{S/L} S/L,分别表示普通座位和爱心座位。

输出格式

输出能够使用杯座人数的最大值。

样例 #1

样例输入 #1

3
SSS

样例输出 #1

3

样例 #2

样例输入 #2

4
SLLS

样例输出 #2

4

样例 #3

样例输入 #3

9
SLLLLSSLL

样例输出 #3

7

提示

【样例 3 解释】

若用 * \texttt * * 来表示杯座,那么座位情况如下:

*   S   *   L   L   *   L   L   *   S   *   S   *   L   L   * \texttt{* S * L L * L L * S * S * L L *} * S * L L * L L * S * S * L L *

【数据规模与约定】

  • 对于 100 % 100\% 100% 的数据, 1 ≤ N ≤ 50 1 \le N \le 50 1N50

【提示与说明】

题目译自 COCI 2011-2012 CONTEST #4 Task 1 KINO

本题分值按 COCI 原题设置,满分 50 50 50

代码如下

#include
#include
#include
#include 


int n, ans, a, x, y;
char s[1001];
int main() {
    scanf("%d", &n);
    scanf("%s",&s);
    for(int i = 0; i < n; i++) {
        ans++;
        if(s[i] != 'L') x = 0;
        else x++, y++;
        if(i > 0 && s[i] == 'L' && s[i - 1] == 'S' && s[i + 1] == 'L' && y != 1) ans--;
        if(x != 1 && x % 2 == 1) ans--;
    }
    printf("%d\n", ans);
    return 0;
}

你可能感兴趣的:(C语言,洛谷,c语言)