深入浅出程序设计竞赛(洛谷基础篇) 第五章 数组与数据批量存储

基于部分读者的建议,本章节补充了本书的电子版链接

电子版教材链接
我通过百度网盘分享的文件:深入浅出程序设计…pdf
链接:https://pan.baidu.com/s/1kmF8wZLnK3Zci7s1ffjRzw
提取码:Ra3Q
复制这段内容打开「百度网盘APP即可获取」

例5-1 小鱼比可爱
#include <iostream>
using namespace std;

int main()
{
	int a[110],n;
	cin >> n;
	for(int i = 0;i<n;i++)
	{
		cin >> a[i]; // 输入每条鱼的可爱值		
	}
	for(int i = 0;i<n;i++)
	{
		int cnt = 0; // 记录每个鱼前面有几条鱼不如自己可爱
		for(int j = i-1;j>=0;j--) // 从第i个位置倒着来找
		{
			if(a[j]<a[i])
				cnt++;   
		}
		cout << cnt << " ";
	}
	return 0;
}
例5-2 小鱼的数字游戏
// 解法一:只使用while循环
#include <iostream>
using namespace std;

int main() 
{
	int a[105]; // 数据范围为最多100个数字
	int count = 0;
	
	int x;
	cin >> x;
	a[0] = x;
	while (x != 0) 
	{
		cin >> x;
		a[++count] = x;
	}
	count--; // count指向最后一个元素的下一个位置
	while (count >= 0) 
	{
		cout << a[count] << " ";
		count--;
	}
	return 0;

}

// 解法二: 只使用for循环
#include <iostream>
using namespace std;

int main()
{
	int a[105],cnt;
    // 输入部分:至多 100 次,遇到 0 就 break
    for (int i = 0; i < 105; i++) 
    {
        int x;
        cin >> x;
        a[i] = x;
        cnt = i;
        if (x == 0) break;

    }
    // 输出部分:倒序输出
    for (int i = cnt-1; i >= 0; i--) 
    {
        cout << a[i] << " ";
    }
    return 0;
}

例5-3 冰雹猜想
#include <iostream>
using namespace std;
#define MAXN 205


int main()
{
	int n,num = 0,a[MAXN];
	cin >> n;
	while(n!=1)
	{
		a[num] = n;
		num++;
		if(n%2 == 0) n/=2;
		else  n=3* n+1;
	}
	a[num] = 1;  // 将最后的1加入数组
	for(int i = num;i>=0;i--) // 倒序输出
		cout << a[i] << ' ';
	return 0;
}
例5-4 校门外的树
前置知识

数组初始化 :

  • a[10010] = {1,2,3} 表示数组的前三个元素被赋值初始化,其它的就默认是0了;
  • 使用memset(数组名,初始化元素,sizeof(数组名))的形式来初始化,但是这种方法需要头文件cstring

#include <iostream>
// #include <cstring>
using namespace std;

int main()
{
	int l,m,a[10010] = {0},a,b,s= 0;
	cin >> l >> m; 
	// 或者使用 memset(a,0,sizeof(a))
	for(int i = 0;i<m;i++)
	{
		cin >> a >> b;
		for(int j = a;j<=b;j++)
		{
			a[j] = 1;  // 把被移除的树状态更改为1
		}
	}
	for(int i = 0;i<=l;i++)
	{
		if(a[i]==0) s++;
	}
	cout << s << endl;
	return 0;
}
例5-5 旗鼓相当的对手
#include <iostream>
#include <cmath>
#define MAXN 1024
using namspace std;

int main()
{
	int n,a[3][MAXN],ans = 0;
	cin >> n;
	for(int i= 1;i<=n;i++)
	{
		cin >> a[0][i] >> a[1][i] >> a[2][i];
	}
	for(int i = 1;i<n;i++)
	{
		for(int j = i+1;j<=n;j++)
		{
			if (abs (a[i][1] - a[j][1]) <= 5 &&
				abs (a[i][2] - a[j][2]) <= 5 &&
				abs (a[i][3] - a[j][3]) <= 5 &&
				abs (sum[i] - sum[j]) <= 10) // 这样看的更清楚一点
				cnt++;
		}
	}
	cout << cnt << endl;
	return 0;
}
例5-6 地毯
#include <iostream>
#include <cstdio>
#include <cstring>
#define MAXN 55
using namespace std;

int main()
{
	int n,m,a[MAXN],b[MAXN];
	memset(a,0,sizeof(a));
	cin >> n >> m;
	for(int i = 1;i<=m;i++)
	{
		int x1,x2,y1,y2;
		cin >> x1 >> y1 >> x2 >> y2;
		for(int j = x1;j<=x2;j++)
		{
			for(int k = y1;k<=y2;k++)
			{
				a[j][k]++;
			}
		}
	}
	for(int i = 1;i<=n;i++)
	{
		for(int j = 1;j<=n;j++)
		{
			cout << a[i][j] << (j == n?'\n':' ');
		}
	}
	return 0;
}
例5-7 工艺品制作
#include <iostream>
#include <cstdio>
using namespace std;

int main()
{
	int v[22][22][22],w,x,h,q,x1,x2,y1,y2,z1,z2,ans;
	cin >> w >> x >> h >> q;
	for(int i = 1;i<=w;i++)
	{
		for(int j = 1;j<=x;j++)
		{
			for(int k = 1;k<=h;k++)
			{
				v[i][j][k] = 1;
			}
		}
	}
	while(q--)
	{
		cin >> x1 >> y1 >> z1 >> x2 >> y2 >> z2;
		for(int i = x1;i<=x2;i++)
		{
			for(int j = y1;j<=y2;j++)
			{
				for(int k = z1;k<=z2;k++)
				{
					v[i][j][k] = 0;
				}
			}
		}
	}
	for(int i = 1;i<=w;i++)
	{
		for(int j = 1;j<=x;j++)
		{
			for(int k = 1;k<=h;k++)
			{
				ans += v[i][j][k];
			}
		}
	}	
	cout << ans << endl;
	return 0;
}
例5-8 彩票摇奖
#include <iostream>
using namespace std;

int main()
{
	int n,a[10],num[10] = {0};
	cin >> n;
	for(int i = 1;i<=n;i++) cin >> a[i];  // 该数组记录中奖号码
	while(n--)
	{
		int ans = 0;
		for(int i = 1;i<=7;i++)
		{
			int x;
			cin >> x;
			for(int j = 1;j<=7;j++)
			{
				if(a[j] == x)  // 比对中奖号码
					ans++;
			}
		}
		num[ans]++;  // 至少有一个号码与中奖号码相同,所以这里默认最低也是六等奖
	}
	for(int i = 7;i>=1;i--)
	{
		cout << num[i] << (i==1?'\n':' ');
	}
	return 0;
	
}
例5-9 神奇的幻方
#include <iostream>
using namespace std;
int n,g[40][40],x,y; 

int main()
{
	cin >> n;
	g[n][n/2 +1 ] =1; 
	x = 1; y = n/2+1; // 初始化状态
	for(int i= 2;i<=n*n;i++ )
	{
		if(x == 1&& y!=n)  // 第一行但不是最后一列
		{
			g[n][y+1] = i, x = n,y++;
		}
		else if(y == n && x!=1) // 最后一列但不是第一行
		{
			g[x-1][1] = i,x--,y = 1
		}
		else if(x == 1 && y == n)  //第一行最后一列
		{
			g[2][n] = i,x = 2;
		}
		else if(x!=1 && y!=n)  // 不在第一行也不在最后一列
		{
			if(g[x-1][y+1] == 0)   // 给右上方填上数
			{
				g[x-1][y+1] = i,x--,y++;
			}
			else
				g[x+1][y] = i,x++;
			continue;  // 注意要跳过该次循环
		}
	}
	for(int i= 1;i<=n;i++)
	{
		for(int j = 1;j<=n;j++)
			cout << g[i][j] << " ";
		cout << endl;
	}
	return 0;
}
例5-10 显示器
前置知识

打表: 指在数据范围小的时候直接列举出所有的情况,符合测试点的要求从而AC过题。


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
char W[10][5][3]=//W[i][j][k]表示第i个数字的第j行的第k列,(手打累死了)
{
	{//0
	'X','X','X',
	'X','.','X',
	'X','.','X',
	'X','.','X',
	'X','X','X',
	},

	{//1
	'.','.','X',
	'.','.','X',
	'.','.','X',
	'.','.','X',
	'.','.','X',
	},

	{//2
	'X','X','X',
	'.','.','X',
	'X','X','X',
	'X','.','.',
	'X','X','X',
	},

	{//3
	'X','X','X',
	'.','.','X',
	'X','X','X',
	'.','.','X',
	'X','X','X',
	},

	{//4
	'X','.','X',
	'X','.','X',
	'X','X','X',
	'.','.','X',
	'.','.','X',
	},

	{//5
	'X','X','X',
	'X','.','.',
	'X','X','X',
	'.','.','X',
	'X','X','X',
	},

	{//6
	'X','X','X',
	'X','.','.',
	'X','X','X',
	'X','.','X',
	'X','X','X',
	},

	{//7
	'X','X','X',
	'.','.','X',
	'.','.','X',
	'.','.','X',
	'.','.','X',
	},

	{//8
	'X','X','X',
	'X','.','X',
	'X','X','X',
	'X','.','X',
	'X','X','X',
	},

	{//9
	'X','X','X',
	'X','.','X',
	'X','X','X',
	'.','.','X',
	'X','X','X',
	}
};
int n;
char s[110];

int main(){

	cin>>n;//输入n
	for(int i=0;i<n;i++)  cin>>s[i];//输入要打印的字符
	
	for(int i=0;i<5;i++){//枚举每一行
		for(int j=0;j<n;j++){//枚举每一个数字
			for(int k=0;k<3;k++)//枚举每个数字的列
	
				cout<<W[s[j]-'0'][i][k];//输出,因为s[j]为字符,所以要减去'0'
				
			if(j!=n-1) cout<<'.'; //如果最后一列,就不需要打印'.'
		}
		cout<<endl;//换行
	}
	return 0;
}
习题5-1 梦中的统计
#include <iostream>
using namespace std;

int N,M,arr[10] = {0};

int main()
{
	cin >> N >> M;
	for(int i = N;i<=M;i++)
	{
		int temp = i;
		while(temp!=0)
		{
			arr[temp%10] ++;
			temp/=10;
		}
	}
	for(int i = 0;i<=9;i++) cout << arr[i] << (i==9?"\n":" ");
	return 0
}
习题5-2 珠心算测试
#include <iostream>
using namespace std;

int main()
{
	int n,a[105],ans = 0;
	cin >> n;
	for(int i = 0;i<n;i++) cin >> a[i];
	
	for(int i = 0;i<n;i++){
		for(int j =i+1;j<n;j++){
			for(int k = 0;k<n;k++){
				if(a[k] == a[j]+a[i])
				{
					bk++;
				}
			}
		}
	}
	cout << bk << endl;
	return 0;
}
习题 5-3 爱与愁的心痛
#include <bits/stdc++.h>
using namespace std;
int n,m,x[300001],sum,ans=2147483647;

int main()
{
	cin >> n >> m;
	for(int i = 1;i<=n;i++) cin >> x[i];
	// 滑动窗口的滑动数为n-m+1;
	for(int i = 1;i<=n-m+1;i++)
	{
		for(int j = i;j<=i+(m-1);j++) // 计算从i开始的长度为m的子序列的和
		{
			sum += x[j];
		}
		ans = min(ans,sum);
		sum = 0;
	}
	cout << ans << endl;
	return 0;
}
习题5-4 牛骨头
#include <bits/stdc++.h>
using namespace std;
int main()
{
	int s1,s2,s3,arr[100000+5],brr[100000+5],crr[100000+5],d[200000+5]={0},ans=0,asf=0;

	cin >> s1 >> s2 >> s3;
	for(int i = 1;i<=s1;i++) arr[i] = i;
	for(int i = 1;i<=s2;i++) brr[i] = i;
	for(int i = 1;i<=s3;i++) crr[i] = i;

	int index = 0;
	for(int i = 1;i<=s1;i++)
		for(int j = 1;j<=s2;j++)
			for(int k = 1;k<=s3;k++)
			{
				int qwe;
				qwe=arr[i]+brr[j]+crr[k];
				d[qwe]++;
			}

	for(int i=1;i<=200000+5;i++){  // 这里的i反映的就是3个骰子的和
		if(d[i]>ans){
			ans=d[i];//判断是不是最大的,由于是如果相等就输出最小所以在判断时是没有=的。
			asf=i;//其实这个才是用来输出的
		}
	}
	cout << asf;
	return 0;
}
习题5-5 开灯
#include <bits/stdc++.h>
using namespace std;
int n;
long ans[2000005];
double a[5000+5];
long t[5000+5];
int main()
{
    cin >> n;
    for(int i= 0;i<n;i++)
    {
        cin >> a[i] >> t[i];
        for(int j = 1;j<=t[i];j++)
        {
            int s = a[i]*j;
            if(ans[s] == 0)
            {
                ans[s] = 1;
            }
            else
            {
                ans[s] = 0;
            }
        }
    }
    for(int i = 1;i<=2000005;i++)
    {
        if(ans[i] == 1)
        {
            cout << i << endl;
            return 0;
        }
    }

    return 0;
}
习题5-6 蛇形方阵
//法一: 打表法
#include <bits/stdc++.h>
using namespace std;
int n;

int main () {
	cin >> n;
	if(n == 1)
		cout << " 1\n";
	
	if(n == 2)
		cout <<" 1 2\n 4 3\n";
	
	if(n == 3) {
		cout << " 1 2 3\n";
		cout << " 8 9 4\n";
		cout << " 7 6 5\n";
	}
	
	if(n == 4) {
		cout << " 1 2 3 4\n";
		cout << " 12 13 14 5\n";
		cout << " 11 15 16 6\n";
		cout << " 10 9 8 7\n";
	}
	
	if(n == 5) {
		cout << " 1 2 3 4 5\n";
		cout << " 16 17 18 19 6\n";
		cout << " 15 24 25 20 7\n";
		cout << " 14 23 22 21 8\n";
		cout << " 13 12 11 10 9\n";
	}
	
	if(n == 6) {
		cout << " 1 2 3 4 5 6\n";
		cout << " 20 21 22 23 24 7\n";
		cout << " 19 32 33 34 25 8\n" ;
		cout << " 18 31 36 35 26 9\n";
		cout << " 17 30 29 28 27 10\n";
		cout << " 16 15 14 13 12 11\n";
	}
	
	if(n == 7) {
		cout << " 1 2 3 4 5 6 7\n";
		cout << " 24 25 26 27 28 29 8\n";
		cout << " 23 40 41 42 43 30 9\n";
		cout << " 22 39 48 49 44 31 10\n";
		cout << " 21 38 47 46 45 32 11\n";
		cout << " 20 37 36 35 34 33 12\n";
		cout << " 19 18 17 16 15 14 13\n";
	}
	
	if(n == 8) {
		cout << " 1 2 3 4 5 6 7 8\n";
		cout << " 28 29 30 31 32 33 34 9\n";
		cout << " 27 48 49 50 51 52 35 10\n";
		cout << " 26 47 60 61 62 53 36 11\n";
		cout << " 25 46 59 64 63 54 37 12\n";
		cout << " 24 45 58 57 56 55 38 13\n";
		cout << " 23 44 43 42 41 40 39 14\n";
		cout << " 22 21 20 19 18 17 16 15\n";
	}
	
	if(n == 9) {
		cout << " 1 2 3 4 5 6 7 8 9\n";
		cout << " 32 33 34 35 36 37 38 39 10\n";
		cout << " 31 56 57 58 59 60 61 40 11\n";
		cout << " 30 55 72 73 74 75 62 41 12\n";
		cout << " 29 54 71 80 81 76 63 42 13\n";
		cout << " 28 53 70 79 78 77 64 43 14\n";
		cout << " 27 52 69 68 67 66 65 44 15\n";
		cout << " 26 51 50 49 48 47 46 45 16\n";
		cout << " 25 24 23 22 21 20 19 18 17\n";
	}
	return 0;
}

// 法二:构造螺旋填充
#include <iostream>
using namespace std;
int n,a[100][100];
int i = 1,x = 1,y = 0;
int main()
{
	scanf(“%d”,&n);
	while(i<=n*n)   
	{
		while(y<n&&!a[x][y+1]) a[x][++y] = i++; // 向右进行移动
		while(x<n&&!a[x+1][y]) a[++x][y] = i++; // 向下进行移动
		while(y>1&&!a[x][y-1]) a[x][--y] = i++; // 向左进行移动
		while(x>1&&!a[x-1][y]) a[--x][y] = i++; // 向上进行移动
	}
	for(int i = 1;i<=n;i++)
	{
		for(int j = a;j<=n;j++)
		{. 
			printf(“%3d”,a[i][j]);
		}
	}
	return 0;
}
习题5-7 杨辉三角
#include<iostream>
using namespace std;

int main()
{
	int n;
	scanf(“%d”,&n);
	for(int i = 1;i<=n;i++)
	{
		a[i][1] = a[i][i] = 1;
	}
	for(int i = 2;i<=n;i++)
	{
		for(int j = 2;j<i;j++)
		{
			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’);
	}
	return 0;
}
习题5-8 插火把
#include <bits/stdc++.h>
using namespace std;
int main()
{
    int n,m,k,crr[110][110] = {0};
    cin >> n >> m >> k;
    for(int i= 1;i<=m;i++)
    {
        int x,y;
        cin >> x >> y;
        crr[x-1][y-1]++;
        crr[x-1][y]++;
        crr[x-1][y+1]++;
        crr[x-2][y]++;
        crr[x][y-2]++;
        crr[x][y-1]++;
        crr[x][y]++;
        crr[x][y+1]++;
        crr[x][y+2]++;
        crr[x+1][y-1]++;
        crr[x+1][y]++;
        crr[x+1][y+1]++;
        crr[x+2][y]++;  
    }
    for(int i = 1;i<=k;i++)
    {
        int o,p;
        cin >> o >> p;
        for(int j = o-2;j<=o+2;j++)
        {
            for(int k = p-2;k<=p+2;k++)
            {
                crr[j][k]++;
            }
        }
    }

    int ans = 0;
    for(int i = 1;i<=n;i++)
    {
        for(int j = 1;j<=n;j++)
        {
            if(crr[i][j] == 0)
            {
                ans++;
            }
        }
    }
    cout << ans << endl;

    return 0;
}
习题5-9 压缩技术
#include<bits/stdc++.h>
using namespace std;
int main()
{
	int n,i=0,sum=0,m;// sum是计数器,m为输入的压缩数字,m表示输出0或1个数 
	cin>>n;//n为点阵边长
	while(cin>>m)//不停输入,按ctrl+z停止输入 
	{
		i++;//利用i记录m的位置,奇数表示连续的0的个数,偶数表示连续的1的个数
		if(i%2!=0) //i%2!=0时此数字表示0的个数 
            for(int j=1;j<=m;j++) //逐个输出0 
            {
                cout<<"0";
                sum++;//每输出1个0,sum值加一 
                if(sum==n)//当sum值达到一行规定数目时 
                {
                    cout<<endl;//换行 
                    sum=0;//sum值清零 
                }
            }
		else  //i%2==0时此数字表示1的个数 
            for(int k=1;k<=m;k++) //逐个输出1 
            {
                cout<<"1";
                sum++;//每输出1个1,sum值加一 
                if(sum==n)//当sum值达到一行规定数目时 
                {
                    cout<<endl;// 换行 
                    sum=0;//sum值清零 
                } 
            }
	}
	return 0;
}
习题5-10 压缩技术(续集版)
#include <bits/stdc++>
using namespace std;

int main()
{
	char c = ‘0’;
	string a[205];
	int sum = 0;
	cin >> a[0];
	len = a[0].size();
	for(int i = 1;i<len;i++) cin >> a[i];
	cout << len << ‘ ’;
	for(int i = 0;i<len;i++)
	{
		for(int j = 0;j<len;j++)
		{
			if(a[i][j] == c) sum++;
			else{
				c = a[i][j];
				cout << sum << ‘ ’;
				sum = 1;
			}
		}
	}
	cout << sum; // 输出最后一个压缩码
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值