洛谷刷题:数组

好累,学习令我快乐


一、小鱼比可爱

题目链接:https://www.luogu.com.cn/problem/P1428

题目描述

人比人,气死人;鱼比鱼,难死鱼。小鱼最近参加了一个“比可爱”比赛,比的是每只鱼的可爱程度。参赛的鱼被从左到右排成一排,头都朝向左边,然后每只鱼会得到一个整数数值,表示这只鱼的可爱程度,很显然整数越大,表示这只鱼越可爱,而且任意两只鱼的可爱程度可能一样。由于所有的鱼头都朝向左边,所以每只鱼只能看见在它左边的鱼的可爱程度,它们心里都在计算,在自己的眼力范围内有多少只鱼不如自己可爱呢。请你帮这些可爱但是鱼脑不够用的小鱼们计算一下。

输入格式

第一行输入一个正整数 n n n,表示鱼的数目。

第二行内输入 n n n 个正整数,用空格间隔,依次表示从左到右每只小鱼的可爱程度 a i a_i ai

输出格式

一行,输出 n n n 个整数,用空格间隔,依次表示每只小鱼眼中有多少只鱼不如自己可爱。

样例 #1

样例输入 #1

6
4 3 0 5 1 2

样例输出 #1

0 0 0 3 1 2

提示

对于 100 % 100\% 100% 的数据, 1 ≤ n ≤ 100 1 \leq n\leq 100 1n100 0 ≤ a i ≤ 10 0 \leq a_i \leq 10 0ai10

代码(python)

n = int(input())

num = list(map(int, input().split(" ")))

nums = []
for i in range(0, n):
    x = 0
    # print("i", i)
    for j in range(0, i):
        if num[i] > num[j]:
            x += 1
    print(x, end=" ")

代码(C)

#include 
#include 

/* run this program using the console pauser or add your own getch, system("pause") or input loop */

int main(int argc, char *argv[]) {
	int n;
	while(scanf("%d",&n)!=EOF){
		int NUM[n];
		int i, j;
		for(i = 0;i < n;i++){
			scanf("%d",&NUM[i]);
		}
		for(j = 0;j < n;j++){
			int sum = 0;
			for(i = 0;i < j;i++){
				if(NUM[j]>NUM[i]){
					sum++;
				}
			}
		printf("%d ",sum);
		}
	} 
	return 0;
}

二、小鱼的数字游戏

题目链接:https://www.luogu.com.cn/problem/P1427

题目描述

小鱼最近被要求参加一个数字游戏,要求它把看到的一串数字 a i a_i ai(长度不一定,以 0 0 0 结束),记住了然后反着念出来(表示结束的数字 0 0 0 就不要念出来了)。这对小鱼的那点记忆力来说实在是太难了,你也不想想小鱼的整个脑袋才多大,其中一部分还是好吃的肉!所以请你帮小鱼编程解决这个问题。

输入格式

一行内输入一串整数,以 0 0 0 结束,以空格间隔。

输出格式

一行内倒着输出这一串整数,以空格间隔。

样例 #1

样例输入 #1

3 65 23 5 34 1 30 0

样例输出 #1

30 1 34 5 23 65 3

提示

数据规模与约定

对于 100 % 100\% 100% 的数据,保证 0 ≤ a i ≤ 2 31 − 1 0 \leq a_i \leq 2^{31} - 1 0ai2311,数字个数不超过 100 100 100

代码(python)


num = list(map(int, input().split(" ")))
n = len(num)

for i in range(0, n-1):
    print(num[n-2-i],end=" ")

代码(C)

#include
int main(){
    int i,a[101];
    for(i=0;;i++){
        scanf("%d",&a[i]);
        if(a[i]==0)
            break;
    }
    int count=i;
    for(i=count-1;i>=0;i--)
        printf("%d ",a[i]);
}

三、【深基5.例3】冰雹猜想

题目链接:https://www.luogu.com.cn/problem/P5727

题目描述

给出一个正整数 n n n,然后对这个数字一直进行下面的操作:如果这个数字是奇数,那么将其乘 3 3 3 再加 1 1 1,否则除以 2 2 2。经过若干次循环后,最终都会回到 1 1 1。经过验证很大的数字( 7 × 1 0 11 7\times10^{11} 7×1011)都可以按照这样的方式比变成 1 1 1,所以被称为“冰雹猜想”。例如当 n n n 20 20 20,变化的过程是 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1 20\to 10\to 5\to 16\to 8\to 4\to 2\to 1 20105168421

根据给定的数字,验证这个猜想,并从最后的 1 1 1 开始,倒序输出整个变化序列。

输入格式

输入一个正整数 n n n

输出格式

输出若干个由空格隔开的正整数,表示从最后的 1 1 1 开始倒序的变化数列。

样例 #1

样例输入 #1

20

样例输出 #1

1 2 4 8 16 5 10 20

提示

数据保证, 1 ≤ n ≤ 100 1 \le n\le 100 1n100

代码(python)

n = int(input())

i = 1
num = {0: n}
while n != 1:
    if n % 2 == 0:
        n = n / 2
        num[i] = n
        i += 1
    else:
        n = n * 3 + 1
        num[i] = n
        i += 1

for j in range(0, i):
    print(int(num[i-1-j]), end=" ")

代码(C)

#include
#include
#include
#include 
 
int main()
{	
	int n;
	scanf("%d",&n);
	
	int num[100000];
	int i = 0; 
	int m = n;
	while(m != 1)
	{
		if(m % 2 ==0)
		{
			m = m/2;
			num[i] = m;
			i++;
		}
		else
		{
			m = m*3 + 1;
			num[i] = m;
			i++;
		}
	}
	
	for(int j = i - 1;j >= 0;j--)
	{
		printf("%d ",num[j]);
	}
	printf("%d\n",n);
	return 0;	
} 

四、[NOIP2005 普及组] 校门外的树

题目链接:https://www.luogu.com.cn/problem/P1047

题目描述

某校大门外长度为 l l l 的马路上有一排树,每两棵相邻的树之间的间隔都是 1 1 1 米。我们可以把马路看成一个数轴,马路的一端在数轴 0 0 0 的位置,另一端在 l l l 的位置;数轴上的每个整数点,即 0 , 1 , 2 , … , l 0,1,2,\dots,l 0,1,2,,l,都种有一棵树。

由于马路上有一些区域要用来建地铁。这些区域用它们在数轴上的起始点和终止点表示。已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分。现在要把这些区域中的树(包括区域端点处的两棵树)移走。你的任务是计算将这些树都移走后,马路上还有多少棵树。

输入格式

第一行有两个整数,分别表示马路的长度 l l l 和区域的数目 m m m

接下来 m m m 行,每行两个整数 u , v u, v u,v,表示一个区域的起始点和终止点的坐标。

输出格式

输出一行一个整数,表示将这些树都移走后,马路上剩余的树木数量。

样例 #1

样例输入 #1

500 3
150 300
100 200
470 471

样例输出 #1

298

提示

【数据范围】

  • 对于 20 % 20\% 20% 的数据,保证区域之间没有重合的部分。
  • 对于 100 % 100\% 100% 的数据,保证 1 ≤ l ≤ 1 0 4 1 \leq l \leq 10^4 1l104 1 ≤ m ≤ 100 1 \leq m \leq 100 1m100 0 ≤ u ≤ v ≤ l 0 \leq u \leq v \leq l 0uvl

【题目来源】

NOIP 2005 普及组第二题

代码(python)

s = input().split()  # .split() 分割字符串,用于读取整行
L = int(s[0])
M = int(s[1])

arr = []

for i in range(L + 1):
    arr.append(True)  # .append() 向arr中添加元素,类似于C++中的.push_back()

for i in range(M):
    s = input().split()
    for j in range(int(s[0]), int(s[1]) + 1):
        arr[j] = False

counter = 0

for i in range(L + 1):
    if arr[i] == True:
        counter += 1

print(counter)

代码(C)


#include
int main()
{
    int l,m;
    scanf("%d%d",&l,&m);
    int tree[l+1],i,j;
    for(i=0;i<=l;i++)
    {
        tree[i]=1;
    }
    int x1,x2;
    for(i=0;i<m;i++)
    {
        scanf("%d%d",&x1,&x2);
        for(j=x1;j<=x2;j++)
        {
            if(tree[j]==1) tree[j]=0;
        }
    }
    int temp=0;
    for(i=0;i<=l;i++)
    {
        if(tree[i]!=0) temp++; 
    }
    printf("%d\n",temp);
 } 

【深基5.例5】五、旗鼓相当的对手

题目连接:https://www.luogu.com.cn/problem/P5728

题目描述

现有 N N N 名同学参加了期末考试,并且获得了每名同学的信息:语文、数学、英语成绩(均为不超过 150 150 150 的自然数)。如果某对学生 < i , j > \text{<}i,j\text{>} <i,j> 的每一科成绩的分差都不大于 5 5 5,且总分分差不大于 10 10 10,那么这对学生就是“旗鼓相当的对手”。现在想知道这些同学中,有几对“旗鼓相当的对手”?同样一个人可能会和其他好几名同学结对。

输入格式

第一行一个正整数 N N N

接下来 N N N 行,每行三个整数,其中第 i i i 行表示第 i i i 名同学的语文、数学、英语成绩。最先读入的同学编号为 1 1 1

输出格式

输出一个整数,表示“旗鼓相当的对手”的对数。

样例 #1

样例输入 #1

3
90 90 90
85 95 90
80 100 91

样例输出 #1

2

提示

数据保证, 2 ≤ N ≤ 1000 2 \le N\le 1000 2N1000 且每科成绩为不超过 150 150 150 的自然数。

代码(python)

n = eval(input())
matrix = [[eval(j) for j in input().split()] for i in range(n)]
c = 0
for i in range(n):
    for j in range(i+1, n):
        if (abs(sum(matrix[i]) - sum(matrix[j])) <= 10) and (abs(matrix[i][0] - matrix[j][0]) <= 5) and (
                abs(matrix[i][1] - matrix[j][1]) <= 5) and (abs(matrix[i][2] - matrix[j][2]) <= 5):
            c+=1
print(c)

代码(C)

#include
#include
#include
#include 
 
int main()
{	
	int n;
	scanf("%d",&n);
	
	int C[n], M[n], E[n];
	for(int i = 0;i < n;i++)
	{
		scanf("%d%d%d",&C[i],&M[i],&E[i]);
	}
	
	int couple = 0;
	for(int i = 0;i < n;i++)
	{
		for(int j = i+1;j < n;j++)
		{
			int num = C[i] + M[i] + E[i];
			int sum = C[j] + M[j] + E[j];
			if(abs(C[i]-C[j]) <= 5&&abs(M[i]-M[j]) <= 5&&abs(E[i]-E[j])<= 5&&abs(num-sum) <= 10)
			{
				couple ++;
			}
		}
	}
	
	printf("%d\n",couple);
	return 0;	
} 

六、【深基5.例7】工艺品制作

题目链接:https://www.luogu.com.cn/problem/P5729

题目描述

现有一个长宽高分别为 w , x , h w,x,h w,x,h 组成的实心玻璃立方体,可以认为是由 1 × 1 × 1 1\times1\times1 1×1×1 的数个小方块组成的,每个小方块都有一个坐标 $ ( i,j,k ) $。现在需要进行 q q q 次切割。每次切割给出 ( x 1 , y 1 , z 1 ) , ( x 2 , y 2 , z 2 ) (x_1,y_1,z_1),(x_2,y_2,z_2) (x1,y1,z1),(x2,y2,z2) 这 6 个参数,保证 x 1 ≤ x 2 x_1\le x_2 x1x2 y 1 ≤ y 2 y_1\le y_2 y1y2 z 1 ≤ z 2 z_1\le z_2 z1z2;每次切割时,使用激光工具切出一个立方体空洞,空洞的壁平行于立方体的面,空洞的对角点就是给出的切割参数的两个点。

换句话说,所有满足 x 1 ≤ i ≤ x 2 x_1\le i\le x_2 x1ix2,$y_1\le j \le y_2 , , z_1\le k\le z_2$ 的小方块 ( i , j , k ) (i,j,k) (i,j,k) 的点都会被激光蒸发。例如有一个 4 × 4 × 4 4\times4\times 4 4×4×4 的大方块,其体积为 64 64 64;给出参数 ( 1 , 1 , 1 ) , ( 2 , 2 , 2 ) (1,1,1),(2,2,2) (1,1,1),(2,2,2) 时,中间的 8 8 8 块小方块就会被蒸发,剩下 56 56 56 个小方块。现在想知道经过所有切割操作后,剩下的工艺品还剩下多少格小方块的体积?

输入格式

第一行三个正整数 w , x , h w,x,h w,x,h

第二行一个正整数 q q q

接下来 q q q 行,每行六个整数 ( x 1 , y 1 , z 1 ) , ( x 2 , y 2 , z 2 ) (x_1,y_1,z_1),(x_2,y_2,z_2) (x1,y1,z1),(x2,y2,z2)

输出格式

输出一个整数表示答案。

样例 #1

样例输入 #1

4 4 4
1
1 1 1 2 2 2

样例输出 #1

56

提示

数据保证, 1 ≤ w , x , h ≤ 20 1\le w,x,h\le 20 1w,x,h20 1 ≤ q ≤ 100 1 \leq q\le 100 1q100 1 ≤ x 1 ≤ x 2 ≤ w 1 \leq x_1 \leq x_2 \leq w 1x1x2w 1 ≤ y 1 ≤ y 2 ≤ x 1 \leq y_1\leq y_2 \leq x 1y1y2x 1 ≤ z 1 ≤ z 2 ≤ h 1 \leq z_1 \leq z_2 \leq h 1z1z2h

代码(python)

w,x,h= map(eval, input().split())
matrix = [[['1' for k in range(h)] for j in range(x)] for i in range(w)]
q=eval(input())
for i in range(q):
    x1,y1,z1,x2,y2,z2= map(eval, input().split())
    for x in range(x1-1,x2):
        for y in range(y1-1,y2):
            for z in range(z1-1,z2):
                matrix[x][y][z]='0'
print(str(matrix).count('1'))

代码(C)

#include
#include
#include
#include 
 
 
int main()
{
	int w,x ,y;
	scanf("%d%d%d",&w,&x,&y);
	int num[w+1][x+1][y+1];
	for(int i = 1;i <= w;i++)
	{
		for(int j = 1;j <= x;j++)
		{
			for(int t = 1;t <= y;t++)
			{
				num[i][j][t] = 1;
			}
		}
	}
	int q;
	scanf("%d",&q);
	long long sum = w*x*y;
	for(int i = 1;i <= q;i++)
	{
		int x1,x2,x3,y1,y2,y3;
		scanf("%d%d%d%d%d%d",&x1,&x2,&x3,&y1,&y2,&y3);
	
		for(int a = x1;a<= y1;a++)
		{
			for(int b= x2;b <= y2;b++)
			{
				for(int c = x3;c <= y3;c++)
				{
					if(num[a][b][c] == 1)
					{
						num[a][b][c] = 0;
						sum --;
					} 
				}
			}
		}
	}
	

	
	printf("%lld\n",sum);
	return 0;
}

七、[AHOI2001] 彩票摇奖

题目链接:https://www.luogu.com.cn/problem/P2550

题目描述

为了丰富人民群众的生活、支持某些社会公益事业,北塔市设置了一项彩票。该彩票的规则是:

  1. 每张彩票上印有 7 7 7 个各不相同的号码,且这些号码的取值范围为 1 ∼ 33 1\sim33 133
  2. 每次在兑奖前都会公布一个由七个各不相同的号码构成的中奖号码。
  3. 共设置 7 7 7 个奖项,特等奖和一等奖至六等奖。

兑奖规则如下:

  • 特等奖:要求彩票上 7 7 7 个号码都出现在中奖号码中。
  • 一等奖:要求彩票上有 6 6 6 个号码出现在中奖号码中。
  • 二等奖:要求彩票上有 5 5 5 个号码出现在中奖号码中。
  • 三等奖:要求彩票上有 4 4 4 个号码出现在中奖号码中。
  • 四等奖:要求彩票上有 3 3 3 个号码出现在中奖号码中。
  • 五等奖:要求彩票上有 2 2 2 个号码出现在中奖号码中。
  • 六等奖:要求彩票上有 1 1 1 个号码出现在中奖号码中。

注:兑奖时并不考虑彩票上的号码和中奖号码中的各个号码出现的位置。例如,中奖号码为 23   31   1   14   19   17   18 23\ 31\ 1\ 14\ 19\ 17\ 18 23 31 1 14 19 17 18,则彩票 12   8   9   23   1   16   7 12\ 8\ 9\ 23\ 1\ 16\ 7 12 8 9 23 1 16 7 由于其中有两个号码( 23 23 23 1 1 1)出现在中奖号码中,所以该彩票中了五等奖。

现已知中奖号码和小明买的若干张彩票的号码,请你写一个程序帮助小明判断他买的彩票的中奖情况。

输入格式

输入的第一行只有一个自然数 n n n,表示小明买的彩票张数;

第二行存放了 7 7 7 个介于 1 1 1 33 33 33 之间的自然数,表示中奖号码;

在随后的 n n n 行中每行都有 7 7 7 个介于 1 1 1 33 33 33 之间的自然数,分别表示小明所买的 n n n 张彩票。

输出格式

依次输出小明所买的彩票的中奖情况(中奖的张数),首先输出特等奖的中奖张数,然后依次输出一等奖至六等奖的中奖张数。

样例 #1

样例输入 #1

2
23 31 1 14 19 17 18
12 8 9 23 1 16 7
11 7 10 21 2 9 31

样例输出 #1

0 0 0 0 0 1 1

提示

数据规模与约定

对于 100 % 100\% 100% 的数据,保证 1 ≤ n < 1000 1 \leq n\lt1000 1n<1000

代码(python)

"""
P2550 [AHOI2001]彩票摇奖(python3实现)
https://www.luogu.com.cn/problem/P2550
"""
n=int( input() )
 
b=list( map( int,input().split() ) )
 
c=[0]*50
 
d=[0]*10
 
for i in range(1,8):
            
            c[ b[i-1] ]=1
 
 
for i in range(1,n+1):
 
            sx=0
 
            a=list( map( int,input().split() ) )
 
            for j in range(1,8):
 
                        if c[a[j-1]]==1:
                                    sx+=1
 
            d[7-sx+1]+=1
 
for i in range(1,8):
            print(d[i],end=" ")
 
 
 
 

代码(C)

#include
int main()
{
	int n,m=7;
	int a[1001][7]={0},b[7]={0}; //把数组定义大一点,不然就会WA 
	
	scanf("%d\n",&n);
	for(int i=0;i<=n;i++)    //存入中奖号码及买入彩票号码 
	{
		for(int j=0;j<7;j++)
		{
			scanf("%d",&a[i][j]);
		}
	}
	
	for(int i=1;i<=n;i++)  
	{
		for(int j=0;j<7;j++)
		{
			for(int k=0;k<7;k++)
			{
				if(a[i][j]==a[0][k])
				m--;
			}
		}
		b[m]++;
		m=7;
	}
	
	for(int i=0;i<7;i++)
	{
		printf("%d ",b[i]);
	}
	
	return 0;
 } 

八、[NOIP2015 提高组] 神奇的幻方

题目链接:https://www.luogu.com.cn/problem/P2615

题目描述

幻方是一种很神奇的 N × N N\times N N×N 矩阵:它由数字 1 , 2 , 3 , ⋯ ⋯   , N × N 1,2,3,\cdots \cdots ,N \times N 1,2,3,⋯⋯,N×N 构成,且每行、每列及两条对角线上的数字之和都相同。

N N N 为奇数时,我们可以通过下方法构建一个幻方:

首先将 1 1 1 写在第一行的中间。

之后,按如下方式从小到大依次填写每个数 K   ( K = 2 , 3 , ⋯   , N × N ) K \ (K=2,3,\cdots,N \times N) K (K=2,3,,N×N)

  1. ( K − 1 ) (K-1) (K1) 在第一行但不在最后一列,则将 K K K 填在最后一行, ( K − 1 ) (K-1) (K1) 所在列的右一列;
  2. ( K − 1 ) (K-1) (K1) 在最后一列但不在第一行,则将 K K K 填在第一列, ( K − 1 ) (K-1) (K1) 所在行的上一行;
  3. ( K − 1 ) (K-1) (K1) 在第一行最后一列,则将 K K K 填在 ( K − 1 ) (K-1) (K1) 的正下方;
  4. ( K − 1 ) (K-1) (K1) 既不在第一行,也不在最后一列,如果 ( K − 1 ) (K-1) (K1) 的右上方还未填数,则将 K K K 填在 ( K − 1 ) (K-1) (K1) 的右上方,否则将 K K K 填在 ( K − 1 ) (K-1) (K1) 的正下方。

现给定 N N N ,请按上述方法构造 N × N N \times N N×N 的幻方。

输入格式

一个正整数 N N N,即幻方的大小。

输出格式

N N N 行,每行 N N N 个整数,即按上述方法构造出的 N × N N \times N N×N 的幻方,相邻两个整数之间用单空格隔开。

样例 #1

样例输入 #1

3

样例输出 #1

8 1 6
3 5 7
4 9 2

样例 #2

样例输入 #2

25

样例输出 #2

327 354 381 408 435 462 489 516 543 570 597 624 1 28 55 82 109 136 163 190 217 244 271 298 325
353 380 407 434 461 488 515 542 569 596 623 25 27 54 81 108 135 162 189 216 243 270 297 324 326
379 406 433 460 487 514 541 568 595 622 24 26 53 80 107 134 161 188 215 242 269 296 323 350 352
405 432 459 486 513 540 567 594 621 23 50 52 79 106 133 160 187 214 241 268 295 322 349 351 378
431 458 485 512 539 566 593 620 22 49 51 78 105 132 159 186 213 240 267 294 321 348 375 377 404
457 484 511 538 565 592 619 21 48 75 77 104 131 158 185 212 239 266 293 320 347 374 376 403 430
483 510 537 564 591 618 20 47 74 76 103 130 157 184 211 238 265 292 319 346 373 400 402 429 456
509 536 563 590 617 19 46 73 100 102 129 156 183 210 237 264 291 318 345 372 399 401 428 455 482
535 562 589 616 18 45 72 99 101 128 155 182 209 236 263 290 317 344 371 398 425 427 454 481 508
561 588 615 17 44 71 98 125 127 154 181 208 235 262 289 316 343 370 397 424 426 453 480 507 534
587 614 16 43 70 97 124 126 153 180 207 234 261 288 315 342 369 396 423 450 452 479 506 533 560
613 15 42 69 96 123 150 152 179 206 233 260 287 314 341 368 395 422 449 451 478 505 532 559 586
14 41 68 95 122 149 151 178 205 232 259 286 313 340 367 394 421 448 475 477 504 531 558 585 612
40 67 94 121 148 175 177 204 231 258 285 312 339 366 393 420 447 474 476 503 530 557 584 611 13
66 93 120 147 174 176 203 230 257 284 311 338 365 392 419 446 473 500 502 529 556 583 610 12 39
92 119 146 173 200 202 229 256 283 310 337 364 391 418 445 472 499 501 528 555 582 609 11 38 65
118 145 172 199 201 228 255 282 309 336 363 390 417 444 471 498 525 527 554 581 608 10 37 64 91
144 171 198 225 227 254 281 308 335 362 389 416 443 470 497 524 526 553 580 607 9 36 63 90 117
170 197 224 226 253 280 307 334 361 388 415 442 469 496 523 550 552 579 606 8 35 62 89 116 143
196 223 250 252 279 306 333 360 387 414 441 468 495 522 549 551 578 605 7 34 61 88 115 142 169
222 249 251 278 305 332 359 386 413 440 467 494 521 548 575 577 604 6 33 60 87 114 141 168 195
248 275 277 304 331 358 385 412 439 466 493 520 547 574 576 603 5 32 59 86 113 140 167 194 221
274 276 303 330 357 384 411 438 465 492 519 546 573 600 602 4 31 58 85 112 139 166 193 220 247
300 302 329 356 383 410 437 464 491 518 545 572 599 601 3 30 57 84 111 138 165 192 219 246 273
301 328 355 382 409 436 463 490 517 544 571 598 625 2 29 56 83 110 137 164 191 218 245 272 299

提示

对于 100 % 100\% 100% 的数据,对于全部数据, 1 ≤ N ≤ 39 1 \leq N \leq 39 1N39 N N N 为奇数。

NOIp2015 提高组 D1T1

代码(python)

n=eval(input())
matrix = [[0 for j in range(n)] for i in range(n)]

matrix[0][n//2]=1
h,l=0,n//2

for k in range(2,n*n+1):
    if h==0 and l!=n-1:h,l=h-1,l+1
    elif l==n-1 and h!=0:h,l=h-1,0
    elif h==0 and l==n-1: h,l=h+1,l
    elif h!=0 and l!=n-1:
        if matrix[h-1][l+1]==0:h,l=h-1,l+1
        else: h,l=h+1,l
    if h <0:h+=n
    if l <0:l+=n
    matrix[h][l]=k
for i in matrix:
    print(' '.join(map(str, i)))

代码(C++)

#include 
using namespace std;

int main() {
    int n,a[50][50]={0};
    cin >> n;
    int h=0,l=n/2;
    a[h][l]=1;
    for (int k = 2; k <= n*n; ++k) {
        if(h==0 && l!=n-1){h=n-1;l++;}
        else if(h==0 && l==n-1)h++;
        else if(l==n-1 && h!=0){h--;l=0;}
        else if(h!=0 && l!=n-1){
            if (a[h-1][l+1]==0){h--;l++;}
            else h++;
        }
        a[h][l]=k;
    }
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            cout<< a[i][j]<<' ';
        }
        cout<<endl;
    }
    return 0;
}

九、【深基5.例10】显示屏

题目链接:https://www.luogu.com.cn/problem/P5730

题目描述

液晶屏上,每个阿拉伯数字都是可以显示成 3 × 5 3\times5 3×5 的点阵的(其中 X 表示亮点,. 表示暗点)。现在给出数字位数(不超过 100 100 100)和一串数字,要求输出这些数字在显示屏上的效果。数字的显示方式如同样例输出,注意每个数字之间都有一列间隔。

输入格式

第一行输入一个正整数 n n n,表示数字的位数。

第二行输入一个长度为 n n n 的自然数。

输出格式

输出五行,表示显示屏上的数字。

样例 #1

样例输入 #1

10
0123456789

样例输出 #1

XXX...X.XXX.XXX.X.X.XXX.XXX.XXX.XXX.XXX
X.X...X...X...X.X.X.X...X.....X.X.X.X.X
X.X...X.XXX.XXX.XXX.XXX.XXX...X.XXX.XXX
X.X...X.X.....X...X...X.X.X...X.X.X...X
XXX...X.XXX.XXX...X.XXX.XXX...X.XXX.XXX

提示

数据保证, 1 ≤ n ≤ 100 1 \leq n \leq 100 1n100

代码(C++)

#include 
#include 
using namespace std;

string s[10][5] = {
    {"XXX", "X.X", "X.X", "X.X", "XXX"},
    {"..X", "..X", "..X", "..X", "..X"},
    {"XXX", "..X", "XXX", "X..", "XXX"},
    {"XXX", "..X", "XXX", "..X", "XXX"},
    {"X.X", "X.X", "XXX", "..X", "..X"},
    {"XXX", "X..", "XXX", "..X", "XXX"},
    {"XXX", "X..", "XXX", "X.X", "XXX"},
    {"XXX", "..X", "..X", "..X", "..X"},
    {"XXX", "X.X", "XXX", "X.X", "XXX"},
    {"XXX", "X.X", "XXX", "..X", "XXX"},
};

int main() {
    int n;
    string ss;
    cin >> n >> ss;
    for (int i=0; i<5; ++i) {
        for (int j=0; j<n; ++j) {
            cout << s[ss[j]-'0'][i];
            if (j != n-1)
                cout << '.';
        }
        cout << '\n';
    }
    return 0;
}

十、梦中的统计

题目链接:https://www.luogu.com.cn/problem/P1554

题目背景

Bessie 处于半梦半醒的状态。过了一会儿,她意识到她在数数,不能入睡。

题目描述

Bessie 的大脑反应灵敏,仿佛真实地看到了她数过的一个又一个数。她开始注意每一个数码( 0 … 9 0 \ldots 9 09):每一个数码在计数的过程中出现过多少次?

给出两个整数 M M M N N N,求在序列 [ M , M + 1 , M + 2 , … , N − 1 , N ] [M, M + 1, M + 2, \ldots, N - 1, N] [M,M+1,M+2,,N1,N] 中每一个数码出现了多少次。

输入格式

1 1 1 行: 两个用空格分开的整数 M M M N N N

输出格式

1 1 1 行: 十个用空格分开的整数,分别表示数码 0 … 9 0 \ldots 9 09 在序列中出现的次数。

样例 #1

样例输入 #1

129 137

样例输出 #1

1 10 2 9 1 1 1 1 0 1

提示

数据保证, 1 ≤ M ≤ N ≤ 2 × 1 0 9 1 \leq M \leq N \leq 2 \times 10^9 1MN2×109 N − M ≤ 5 × 1 0 5 N-M \leq 5 \times 10^5 NM5×105

代码(python)

 
a=[0]*1010
 
n,m=map( int,input().split() )
 
for i in range(n,m+1):
            j=i
            while j>0:
                        a[j%10]+=1
                        j//=10
 
for i in range(10):
            print(a[i],end=" ")
 
 

代码(C)

 
#include
#include
#include 

int main(){
	int i,n1,n2,b;
	int a[10]={0};
	scanf("%d %d",&n1,&n2);
	for(i=n1;i<=n2;i++){
		int num=i;
		while(num>0){
			b=num%10;
			num=num/10;
			a[b]++;
		}
	}
	for(i=0;i<10;i++){
		printf("%d ",a[i]);
	}
	return 0;
} 

十一、[NOIP2014 普及组] 珠心算测验

题目链接:https://www.luogu.com.cn/problem/P2141

题目背景

NOIP2014 普及 T1

题目描述

珠心算是一种通过在脑中模拟算盘变化来完成快速运算的一种计算技术。珠心算训练,既能够开发智力,又能够为日常生活带来很多便利,因而在很多学校得到普及。

某学校的珠心算老师采用一种快速考察珠心算加法能力的测验方法。他随机生成一个正整数集合,集合中的数各不相同,然后要求学生回答:其中有多少个数,恰好等于集合中另外两个(不同的)数之和?

最近老师出了一些测验题,请你帮忙求出答案。

输入格式

共两行,第一行包含一个整数 n n n,表示测试题中给出的正整数个数。

第二行有 n n n 个正整数,每两个正整数之间用一个空格隔开,表示测试题中给出的正整数。

输出格式

一个整数,表示测验题答案。

样例 #1

样例输入 #1

4
1 2 3 4

样例输出 #1

2

提示

【样例说明】

1 + 2 = 3 , 1 + 3 = 4 1+2=3,1+3=4 1+2=3,1+3=4,故满足测试要求的答案为 2 2 2

注意,加数和被加数必须是集合中的两个不同的数。

【数据说明】

对于 100 % 100\% 100% 的数据, 3 ≤ n ≤ 100 3 \leq n \leq 100 3n100,测验题给出的正整数大小不超过 10 , 000 10,000 10,000

代码(python)


n=input().split()
l=input().split()

s=set(l)
l=list(s)
ans=set(l)
cnt=0
ans.clear()
for i in range(0,len(l)):
    x=int(l[i])
    for j in range(i+1,len(l)):
        y=int(l[j])
        if str(x+y) in s:
            if str(x+y) in ans:
                continue
            else:
                cnt+=1
                ans.add(str(x+y))


print (len(ans))

代码(C)

#include
#include
int a[110];
int n;
int num=0;   //答案数量
int v[110];  //判断去重
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
       scanf("%d",&a[i]);
    for(int i=1;i<n;i++)   //左边界
       for(int j=i+1;j<=n;j++)   //右边界
          for(int k=1;k<=n;k++)   //无脑暴搜
             if(k!=i&&k!=j&&a[i]+a[j]==a[k]&&v[k]==0)   //没有数过并且不是边界
                {
                   num++;
                   v[k]=1;   //用过啦~
                }
    printf("%d",num);
    //system("pause");   //无视这一行~
    return 0;
}

十二、爱与愁的心痛

题目链接:https://www.luogu.com.cn/problem/P1614

题目背景

(本道题目隐藏了两首歌名,找找看哪~~~)

《爱与愁的故事第一弹·heartache》第一章。

《我为歌狂》当中伍思凯神曲《舞月光》居然没赢给萨顶顶,爱与愁大神心痛啊~~~而且最近还有一些令人伤心的事情,都让人心痛(最近真的很烦哈)……

题目描述

最近有 n n n 个不爽的事,每句话都有一个正整数刺痛值(心理承受力极差)。爱与愁大神想知道连续 m m m 个刺痛值的和的最小值是多少,但是由于业务繁忙,爱与愁大神只好请你编个程序告诉他。

输入格式

第一行有两个用空格隔开的整数,分别代表 n n n m m m

2 2 2 到第 ( n + 1 ) (n + 1) (n+1) 行,每行一个整数,第 ( i + 1 ) (i + 1) (i+1) 行的整数 a i a_i ai 代表第 i i i 件事的刺痛值 a i a_i ai

输出格式

输出一行一个整数,表示连续 m m m 个刺痛值的和的最小值是多少。

样例 #1

样例输入 #1

8 3
1
4
7
3
1
2
4
3

样例输出 #1

6

提示

数据规模与约定
  • 对于 30 % 30\% 30% 的数据,保证 n ≤ 20 n \leq 20 n20
  • 对于 60 % 60\% 60% 的数据,保证 n ≤ 100 n \leq 100 n100
  • 对于 90 % 90\% 90% 的数据,保证 n ≤ 1 0 3 n \leq 10^3 n103
  • 对于 100 % 100\% 100% 的数据,保证 0 ≤ m ≤ n ≤ 3 × 1 0 3 0 \leq m \leq n \leq 3 \times 10^3 0mn3×103 1 ≤ a i ≤ 100 1 \leq a_i \leq 100 1ai100

代码(python)


a = [0] * 100010
h = [0] * 100010
n, m = map(int, input().split())
b = []
for i in range(n):
    x = input()
    b.append(int(x))

for i in range(n):
    a[i] = b[i]


c = [0] * (n - m + 1)
for i in range(n - m + 1):
    for k in range(i, i + m):
        h[i] = h[i] + a[k]
    c[i] = h[i]
c.sort()
print(c[0])


代码(C)

#include 
#include 
#define M 300000
int main(int argc, char *argv[]) {
	int n, m;
	scanf("%d%d",&n,&m);
		int NUM[M];
		int i, j;
		for(i = 0;i < n;i++){
			scanf("%d",&NUM[i]); 
		} 
		long long int sum = 0, all = 1000000;
		for(i = 0;i < n-m+1;i++){
			for(j = i;j < m+i;j++){
				sum  = NUM[j] + sum;
				}
				if(sum < all){
					all = sum;	
			}
			sum = 0;
		}
		printf("%lld",all); 
	return 0;
}

十三、[USACO08OCT] Bovine Bones G

题目链接:https://www.luogu.com.cn/problem/P2911

题面翻译

贝茜喜欢玩棋盘游戏和角色扮演游戏,所以她说服了约翰开车带她去小商店.在那里她买了三个骰子。这三个不同的骰子的面数分别为 s 1 , s 2 , s 3 s_1,s_2,s_3 s1,s2,s3

对于一个有 S S S 个面的骰子每个面上的数字是 1 , 2 , 3 , … , S 1,2,3,\ldots,S 1,2,3,,S。每个面(上的数字)出现的概率均等。贝茜希望找出在所有“三个面上的数字的和”中,哪个和的值出现的概率最大。

现在给出每个骰子的面数,需要求出哪个所有“三个面上的数字的和”出现得最频繁。如果有很多个和出现的概率相同,那么只需要输出最小的那个。

数据范围: 2 ≤ s 1 ≤ 20 2\le s_1\leq 20 2s120 2 ≤ s 2 ≤ 20 2 \leq s_2\leq 20 2s220 2 ≤ s 3 ≤ 40 2 \leq s_3\leq 40 2s340

题目描述

Bessie loves board games and role-playing games so she persuaded Farmer John to drive her to the hobby shop where she purchased three dice for rolling. These fair dice have S1, S2, and S3 sides

respectively (2 <= S1 <= 20; 2 <= S2 <= 20; 2 <= S3 <= 40).

Bessie rolls and rolls and rolls trying to figure out which three-dice sum appears most often.

Given the number of sides on each of the three dice, determine which three-dice sum appears most frequently. If more than one sum can appear most frequently, report the smallest such sum.

POINTS: 70

输入格式

* Line 1: Three space-separated integers: S1, S2, and S3

输出格式

* Line 1: The smallest integer sum that appears most frequently when the dice are rolled in every possible combination.

样例 #1

样例输入 #1

3 2 3

样例输出 #1

5

提示

Here are all the possible outcomes.

1 1 1 -> 3  
1 2 1 -> 4  
2 1 1 -> 4  
2 2 1 -> 5  
3 1 1 -> 5  
3 2 1 -> 6 
1 1 2 -> 4  
1 2 2 -> 5  
2 1 2 -> 5  
2 2 2 -> 6  
3 1 2 -> 6  
3 2 2 -> 7 
1 1 3 -> 5  
1 2 3 -> 6  
2 1 3 -> 6  
2 2 3 -> 7  
3 1 3 -> 7  
3 2 3 -> 8

Both 5 and 6 appear most frequently (five times each), so 5 is the answer.

代码(python)



flag = [0] * 100010

s1, s2, s3 = map(int, input().split())

for i in range(1, s1 + 1):
    for j in range(1, s2 + 1):
        for z in range(1, s3 + 1):
            flag[i + j + z] += 1

sum = 0
ans = -2147483647
tmp = 0

for i in range(1, s1 * s2 * s3 + 1):

    sum = flag[i]

    if sum > ans:
        ans = sum
        tmp = i

print(tmp)


代码(C)

#include
#include
#include
#include 

int main()
{	
	int s1, s2, s3;
	scanf("%d%d%d",&s1,&s2,&s3);
	
	int sum = 0;
	int m = s1 + s2 + s3;
	int num[m+1];
	for(int i = 3;i <= m;i++)
	{
		num[i] = 0;
	}
	for(int i = 1;i <= s1;i++)
	{
		for(int j = 1;j <= s2;j++)
		{
			for(int t = 1;t <= s3;t++)
			{
				
				sum = i + j + t;
				num[sum]++;

			}
		}
	}
	int min = 0;
	int ans = 0;
	for(int i = 3;i <= m;i++)
	{
		if(num[i] > min)
		{
			min = num[i];
			ans = i;
		}
	}
	
	printf("%d\n",ans);
	return 0;
}

十四、开灯

题目链接:https://www.luogu.com.cn/problem/P1161

题目描述

在一条无限长的路上,有一排无限长的路灯,编号为 1 , 2 , 3 , 4 , … 1,2,3,4,\dots 1,2,3,4,

每一盏灯只有两种可能的状态,开或者关。如果按一下某一盏灯的开关,那么这盏灯的状态将发生改变。如果原来是开,将变成关。如果原来是关,将变成开。

在刚开始的时候,所有的灯都是关的。小明每次可以进行如下的操作:

指定两个数, a , t a,t a,t a a a 为实数, t t t 为正整数)。将编号为 ⌊ a ⌋ , ⌊ 2 × a ⌋ , ⌊ 3 × a ⌋ , … , ⌊ t × a ⌋ \lfloor a\rfloor,\lfloor 2 \times a\rfloor,\lfloor3 \times a\rfloor,\dots,\lfloor t \times a\rfloor a,2×a,3×a,,t×a 的灯的开关各按一次。其中 ⌊ k ⌋ \lfloor k \rfloor k 表示实数 k k k 的整数部分。

在小明进行了 n n n 次操作后,小明突然发现,这个时候只有一盏灯是开的,小明很想知道这盏灯的编号,可是这盏灯离小明太远了,小明看不清编号是多少。

幸好,小明还记得之前的 n n n 次操作。于是小明找到了你,你能帮他计算出这盏开着的灯的编号吗?

输入格式

第一行一个正整数 n n n,表示 n n n 次操作。

接下来有 n n n 行,每行两个数, a i , t i a_i,t_i ai,ti。其中 a i a_i ai 是实数,小数点后一定有 6 6 6 位, t i t_i ti 是正整数。

输出格式

仅一个正整数,那盏开着的灯的编号。

样例 #1

样例输入 #1

3
1.618034 13
2.618034 7
1.000000 21

样例输出 #1

20

提示

T = ∑ i = 1 n t i = t 1 + t 2 + t 3 + ⋯ + t n T=\sum \limits_{i=1}^n t_i = t_1+t_2+t_3+\dots+t_n T=i=1nti=t1+t2+t3++tn

  • 对于 30 % 30\% 30% 的数据,满足 T ≤ 1000 T \le 1000 T1000
  • 对于 80 % 80\% 80% 的数据,满足 T ≤ 200000 T \le 200000 T200000
  • 对于 100 % 100\% 100% 的数据,满足 T ≤ 2000000 T \le 2000000 T2000000
  • 对于 100 % 100\% 100% 的数据,满足 n ≤ 5000 n \le 5000 n5000 1 ≤ a i < 1000 1 \le a_i<1000 1ai<1000 1 ≤ t i ≤ T 1 \le t_i \le T 1tiT

数据保证,在经过 n n n 次操作后,有且只有一盏灯是开的,不必判错。而且对于所有的 i i i 来说, t i × a i t_i\times a_i ti×ai 的最大值不超过 2000000 2000000 2000000

代码(python)


 
a=[0]*2000001
 
n=int(input())
 
for i in range(1,n+1):
 
            x,y=map( float,input().split() )
 
            for j in range(1,int(y+1) ):
 
                        if a[int(j*x)]==0:
                                    a[int(j*x)]=1
 
                        else:
                                    a[int(j*x)]=0
 
 
i=1
 
while 1:
            if a[i]==1:
                        print(i)
                        break
            i+=1
 
 
 

代码(C)

#include
#include
#include
#include
#include
#define f(i,j,n) for(i=j;i<=n;i++) //for循环简写,福利福利~

int main(){
  
    int n, t, i, j, ans = 0;
    double a;
    scanf("%d", &n);
    f(i, 1, n){
        scanf("%lf %d", &a, &t);
        f(j,1,t)				//每一次再循环t次 
            ans ^= (int)(j*a); //重点:位运算,直接异或。这里注意要用int强制把j*a的值转换成整型
    }
    printf("%d", ans); //输出ans即可
    return 0; 
}

十五、【深基5.习6】蛇形方阵

题目链接:https://www.luogu.com.cn/problem/P5731

题目描述

给出一个不大于 9 9 9 的正整数 n n n,输出 n × n n\times n n×n
的蛇形方阵。

从左上角填上 1 1 1 开始,顺时针方向依次填入数字,如同样例所示。注意每个数字有都会占用 3 3 3 个字符,前面使用空格补齐。

输入格式

输入一个正整数 n n n,含义如题所述。

输出格式

输出符合题目要求的蛇形矩阵。

样例 #1

样例输入 #1

4

样例输出 #1

1  2  3  4
 12 13 14  5
 11 16 15  6
 10  9  8  7

提示

数据保证, 1 ≤ n ≤ 9 1 \leq n \leq 9 1n9

代码(python)

n=eval(input())
matrix = [[0 for j in range(n)] for i in range(n)]
x,y=0,0

towards=['y=y+1','x+=1','y-=1','x-=1']
t=0
for i in range(1,n*n+1):
   matrix[x][y]=i
   exec(towards[t])
   if x>n-1 or y>n-1 or matrix[x][y]!=0:
      exec(towards[(t+2)%4])
      t=(t+1)%4
      exec(towards[t])
for i in (matrix):
   for j in i:
      print(f"{j: >3}",end='')
   print()

代码(C)

#include
#include
#include
#include 
int num = 1, a[12][12];
int main() {
	int n;
	scanf("%d",&n);
	int t = ceil(1.0 * n / 2);根据推导总结,转的圈数为行数除以2,如果行数是奇数还要+1,其实就是ceil。
	for(int i=0; i<t; i++) {
		for (int j = i; j < n - i; j++) {
            a[i][j] = num++;//每一圈判断第一行
        }
        for (int j = i + 1; j < n - i - 1; j++) {
            a[j][n - i - 1] = num++;//每一圈判断最后一列
        }
        for (int j = n - i - 1; j > i; j--) {
            a[n - i - 1][j] = num++;//判断每一圈最后一行
        }
        for (int j = n - i - 1; j > i; j--)  {
            a[j][i] = num++;//判断每一圈第一列
        }
	}
	for(int i=0; i<n; i++) {
		for(int j=0; j<n; j++) {
			printf("%3d", a[i][j]);//输出方式要注意,%3d
		}
		printf("\n");
	}
	return 0;
} 

十六、【深基5.习7】杨辉三角

题目链接:https://www.luogu.com.cn/problem/P5732

题目描述

给出 n ( n ≤ 20 ) n(n\le20) n(n20),输出杨辉三角的前 n n n 行。

如果你不知道什么是杨辉三角,可以观察样例找找规律。

输入格式

输出格式

样例 #1

样例输入 #1

6

样例输出 #1

1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1

代码(python)


n = int(input())
b = [[0] * n for t in range(n)]
for i in range(n):
    b[i][0] = 1
    b[i][i] = 1
for i in range(n):
    for j in range(1, i):
        b[i][j] = b[i - 1][j] + b[i - 1][j - 1]

for i in range(n):
    for j in range(i + 1):
        print(b[i][j], end=' ')
    print()


代码(c)

#include
#include
#include
#include 

int a[21][21];
int main()
{
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		a[i][1]=a[i][i]=1;//赋初值
	for(int i=1;i<=n;i++)
		for(int j=2;j<i;j++)//因为a[i][1]、a[i][i]已经赋值过了,所以循环是2~n-1
			a[i][j]=a[i-1][j]+a[i-1][j-1];
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=i;j++)
			printf("%d ",a[i][j]);
		printf("\n");
	}
}

十七、【Mc生存】插火把

题目链接:https://www.luogu.com.cn/problem/P1789

题目描述

话说有一天 linyorson 在“我的世界”开了一个 n × n n \times n n×n 的方阵,现在他有 m m m 个火把和 k k k 个萤石,分别放在 ( x 1 , y 1 ) ∼ ( x m , y m ) (x_1, y_1) \sim (x_m, y_m) (x1,y1)(xm,ym) ( o 1 , p 1 ) ∼ ( o k , p k ) (o_1, p_1) \sim (o_k, p_k) (o1,p1)(ok,pk) 的位置,没有光并且没放东西的地方会生成怪物。请问在这个方阵中有几个点会生成怪物?

P.S. 火把的照亮范围是:

    |暗|暗| 光 |暗|暗|
    |暗|光| 光 |光|暗|
    |光|光|火把|光|光|
    |暗|光| 光 |光|暗|
    |暗|暗| 光 |暗|暗|

萤石:

    |光|光| 光 |光|光|
    |光|光| 光 |光|光|
    |光|光|萤石|光|光|
    |光|光| 光 |光|光|
    |光|光| 光 |光|光|

输入格式

输入共 m + k + 1 m + k + 1 m+k+1 行。
第一行为 n , m , k n, m, k n,m,k
2 2 2 到第 m + 1 m + 1 m+1 行分别是火把的位置 x i , y i x_i, y_i xi,yi
m + 2 m + 2 m+2 到第 m + k + 1 m + k + 1 m+k+1 行分别是萤石的位置 o i , p i o_i, p_i oi,pi

注:可能没有萤石,但一定有火把。

输出格式

有几个点会生出怪物。

样例 #1

样例输入 #1

5 1 0
3 3

样例输出 #1

12

提示

数据保证, 1 ≤ n ≤ 100 1 \le n \le 100 1n100 1 ≤ m + k ≤ 25 1 \leq m+k \leq 25 1m+k25 1 ≤ m ≤ 25 1 \leq m \leq 25 1m25 0 ≤ k ≤ 5 0 \leq k \leq 5 0k5

代码(python)

# 读数据到数组中
def readToArray():
    s = input()
    nums = s.strip().split()
    nums = [int(num) for num in nums]
    return nums

n,m,k = readToArray()[0:3]
arr = [[0 for i in range(n+5)] for i in range(n+5)]

# 根据火把修改位置
def modifyFire(x,y):
    for i in range(-1,2):
        for j in range (-1,2):
            nx = x+i
            ny = y+j
            if nx>0 and nx<=n and ny >0 and ny <= n:
                arr[nx][ny] = 1 # 修改值

    # 修改零散点
    if y -2 > 0 :
        arr[x][y-2] = 1
    if x-2>0:
        arr[x-2][y] = 1
    if x+2 <= n:
        arr[x+2][y] = 1
    if y+2 <= n :
        arr[x][y+2] = 1

def modifyStone(x,y):
    for i in range(-2, 3):
        for j in range(-2, 3):
            nx = x + i
            ny = y + j
            if nx > 0 and nx <= n and ny > 0 and ny <= n:
                arr[nx][ny] = 1  # 修改值

#输入火把
for i in range(m):
    x,y = readToArray()[0:2]
    # 根据火把的位置遍历去修改数组
    modifyFire(x,y)

for i in range(k):
    x,y = readToArray()[0:2]
    modifyStone(x,y)

cnt = 0
for i in range(1,n+1):
    for j in range(1,n+1):
        if arr[i][j] == 0:
            cnt+=1
print(cnt)

代码(c)

#include

int n,m,k,x,y,i,j,u,v,ans;//n,m,k(题目),x,y(临时坐标),i,j,u,v(循环变量),ans(答案)。

int main(){
	int ma[1000][1000];//自己试了几次,数据只有这么大……
    scanf("%d %d %d", &n, &m, &k);
    for(i=1;i<=m;i++){//火把
        scanf("%d %d", &x, &y);
        ma[x-2][y]=ma[x-1][y+1]=ma[x-1][y]=ma[x-1][y-1]=ma[x][y+2]=ma[x][y+1]=ma[x][y]=ma[x][y-1]=ma[x][y-2]=ma[x+1][y+1]=ma[x+1][y]=ma[x+1][y-1]=ma[x+2][y]=1;//要标记有光的。(慢慢打,有点麻烦。)
    }
    for(i=1;i<=k;i++){//萤石
        scanf("%d %d", &x, &y);
        for(u=-2;u<=2;u++)
            for(v=-2;v<=2;v++)
                ma[x+u][y+v]=1;//萤石用循环标记,代码就短一些。
    }
    for(i=1;i<=n;i++)
        for(j=1;j<=n;j++)
            if(ma[i][j]==0)
                ans++;
    printf("%d", ans);
    return 0;
}

十八、压缩技术

题目链接:https://www.luogu.com.cn/problem/P1319

题目描述

设某汉字由 N × N N \times N N×N 0 \texttt 0 0 1 \texttt 1 1 的点阵图案组成。

我们依照以下规则生成压缩码。连续一组数值:从汉字点阵图案的第一行第一个符号开始计算,按书写顺序从左到右,由上至下。第一个数表示连续有几个 0 \texttt 0 0,第二个数表示接下来连续有几个 1 \texttt 1 1,第三个数再接下来连续有几个 0 \texttt 0 0,第四个数接着连续几个 1 \texttt 1 1,以此类推……

例如: 以下汉字点阵图案:

0001000
0001000
0001111
0001000
0001000
0001000
1111111

对应的压缩码是: 7   3   1   6   1   6   4   3   1   6   1   6   1   3   7 \texttt {7 3 1 6 1 6 4 3 1 6 1 6 1 3 7} 7 3 1 6 1 6 4 3 1 6 1 6 1 3 7 (第一个数是 N N N ,其余各位表示交替表示0和1 的个数,压缩码保证 N × N = N \times N= N×N= 交替的各位数之和)

输入格式

数据输入一行,由空格隔开的若干个整数,表示压缩码。

其中,压缩码的第一个数字就是 N N N,表示这个点阵应当是 N × N N\times N N×N 的大小。

接下来的若干个数字,含义如题目描述所述。

输出格式

输出一个 N × N N\times N N×N 的 01 矩阵,表示最后的汉字点阵图(点阵符号之间不留空格)。

样例 #1

样例输入 #1

7 3 1 6 1 6 4 3 1 6 1 6 1 3 7

样例输出 #1

0001000
0001000
0001111
0001000
0001000
0001000
1111111

提示

样例解释

洛谷刷题:数组_第1张图片

数据范围

数据保证, 3 ≤ N ≤ 200 3\leq N\leq 200 3N200

代码(python)




t = 0

a = list(map(int, input().split()))

n = a[0]

i = 0
s = 0

while s < n * n:
    i += 1

    b = a[i]
    while b >= 1:
        if t == n:
            print()
            t = 0

        if i % 2 == 1:
            print("0", end='')
        else:
            print("1", end='')
        t += 1
        s += 1
        b -= 1

print()



代码(C)

#include 
#include 

/* run this program using the console pauser or add your own getch, system("pause") or input loop */

int main(int argc, char *argv[]) {
	int N;
	scanf("%d",&N);//找到行数 
	int sum = 0, spot = 0, count = 0;
	while(sum < N*N){
		
		int n;
		scanf("%d",&n);
		for(int i = 0;i < n;i++){
			printf("%d",spot);
			count++;
			sum++;
			if(count == N){
				printf("\n");
				count = 0;
			}
		}
		if(spot == 1)
			spot = 0;
		else
			spot = 1;
	} 
	return 0;
}

十九、压缩技术(续集版)

题目链接:https://www.luogu.com.cn/problem/P1320

题目描述

设某汉字由 N × N N \times N N×N 0 \texttt 0 0 1 \texttt 1 1 的点阵图案组成。

我们依照以下规则生成压缩码。连续一组数值:从汉字点阵图案的第一行第一个符号开始计算,按书写顺序从左到右,由上至下。第一个数表示连续有几个 0 \texttt 0 0,第二个数表示接下来连续有几个 1 \texttt 1 1,第三个数再接下来连续有几个 0 \texttt 0 0,第四个数接着连续几个 1 \texttt 1 1,以此类推……

例如: 以下汉字点阵图案:

0001000
0001000
0001111
0001000
0001000
0001000
1111111

对应的压缩码是: 7   3   1   6   1   6   4   3   1   6   1   6   1   3   7 \texttt {7 3 1 6 1 6 4 3 1 6 1 6 1 3 7} 7 3 1 6 1 6 4 3 1 6 1 6 1 3 7 (第一个数是 N N N ,其余各位表示交替表示0和1 的个数,压缩码保证 N × N = N \times N= N×N= 交替的各位数之和)

输入格式

汉字点阵图(点阵符号之间不留空格)。

输出格式

输出一行,压缩码。

样例 #1

样例输入 #1

0001000
0001000
0001111
0001000
0001000
0001000
1111111

样例输出 #1

7 3 1 6 1 6 4 3 1 6 1 6 1 3 7

提示

数据保证, 3 ≤ N ≤ 200 3\leq N\leq 200 3N200

代码(python)

a = list(input())
a.pop()
n = len(a)
for i in range(n-2) :
    a += list(input())
    a.pop()
a += list(input()) #就不知道为什么最后一行的换行符是不读入的,
               #加了这个就ac了
b = a.copy()
# b.pop()

t = 0
flag = '0'
print(n,end=' ')
i = 0
while i < n * n :
    while (i < n * n and b[i] == flag) :
        t += 1
        i += 1
    if i >= n * n :
        print(t)
    else :
        print(t,end=' ')
        t = 0
        flag = str(1 - int(flag))

代码(C)

#include 
#include 
#include 
int main(void)
{
	int i,n,count=0;
	char str[40000],temp[200];
	int a[40000],len;
	
	while((scanf("%s",temp))!=EOF)
		strcat(str,temp);
	len=strlen(str);
	n=(int)sqrt(len);
	
	for(i=0;i<=len;i++)
		a[i]=str[i]-'0';
	
	if(a[0]==1)
	{
		printf("%d 0 ",n);
		i++;
	}
	else
		printf("%d ",n);
		
	for(i=0;i<len-1;i++)
	{
		if(a[i]==a[i+1])
			count++;
		else
		{
			printf("%d ",++count);
			count=0;
		}
	}
	if(a[len-2]==a[len-1])
		printf("%d",++count);
	else
		printf("1");
	return 0;
}

你可能感兴趣的:(C语言学习,python学习,python,算法,开发语言)