CSP-CCF 202203-1 未初始化警告

目录

一、问题描述

二、解答

1. 50分版:显示运行超时

2. 90分版:依然显示运行超时

3.100分版

方法一:定义一个整型数组a[N]

方法二:定义一个bool型数组b[N]

方法三:使用map库

三、总结


一、问题描述

二、解答

1. 50分版:显示运行超时

思路:定义两个数组x和y,使用双重循环,先将初始化的数目求出来,再用k减去

评价:能达到结果,但是太复杂,会显示运行超时

#include<iostream>
using namespace std;
int main()
{
	int n, k;
	cin >> n >> k;
	int x[100001] = { 0 };
	int y[100001] = { 0 };
	for (int i = 1; i <= k; i++)
	{
		cin >> x[i] >> y[i];
	}
	int num = 0;
	//逆向思维,求出被初始化的数量
	//注意是求未初始化的情况!!!
	for (int i = 1; i <= k; i++)
	{
		if (y[i] == 0)
		{
			num++;
		}
		else{
		int time = 0;
		for (int j = 1; j < i; j++)
		{
			if ((x[j] == y[i]&&time==0))
			{
				num++;
				time=1;
			}
			//要考虑到有x有重复的情况
		}
		}
	}
	int num_no = k - num;
	cout << num_no<< endl;
	return 0;
}

2. 90分版:依然显示运行超时

思路:和前一版类似,但是简化了部分逻辑,如:在输入的时候就进行判断;if语句也去掉了time(记录x的首次出现),直接在检测到前面的x[j]有与当前的y[i]有相等的情况就break,退出当前循环。

评价:虽然进行了一定程度上的简化,依然会显示超时,得不到满分

#include<iostream>
using namespace std;
#define N 100001
int x[N] = { 0 };
int y[N] = { 0 };
int main()
{
	int n, k;
	cin >> n >> k;

	int num = 0;

	for (int i = 1; i <= k; i++)
	{	
        cin >> x[i] >> y[i];
		if(y[i]!=0)
		{ 
		for (int j = 1; j < i; j++)
		{
			if (x[j] == y[i])
			{
				num++;
				break;
			}
			//要考虑到有x有重复的情况
		}
		}
		else
		{
			num++;
		}
		
	}
	int num_no = k - num;
	cout << num_no << endl;
	return 0;
}

3.100分版

在经过前面反复的简化,依然得不到满分后,无奈上网查找其他办法。

最后决定放弃定义两个数组和双重循环

方法一:定义一个整型数组a[N]
#include<iostream>
using namespace std;
#define N 100001
int a[N] = { 0 };
int main()
{
	int n, k;
	cin >> n >> k;
	int num = 0;
	for (int i = 1; i <= k; i++)
	{
        a[0] = 1;
       //不写这个的话,if条件就改为if (a[y] == 0&&y!=0)
        int x, y;
		cin >> x >> y;
		if (a[y] == 0)
		{
			num++;
		}
		a[x] = 1;//或者写成a[x]++;
	
	}
	cout << num << endl;
	return 0;
}
方法二:定义一个bool型数组b[N]
#include<iostream>
using namespace std;
#define N 100001
bool b[N];
int main()
{
	int n, k;
	cin >> n >> k;
	int num = 0;
	for (int i = 1; i <= k; i++)
	{
        b[0]=true;
        int x, y;
		cin >> x >> y;
		//if (x)等价于if (x!=0)、if (!x)等价于if (x==0)
		if(!b[y])
		{
			num++;
		}
		b[x]=true;
	
	}
	cout << num << endl;
	return 0;
}
方法三:使用map库

注:快速判断之前是否存在这个值,应该想到使用map,使用一个map来记录左值的下标出现次数,每接收一对左、右值,当右值非常量且右值之前不在map中,结果加一,对于所有的都要左值加一。

#include<iostream>
#include<map>
using namespace std;
int main()
{
	map<int, int>mp;//定义一个映射
	int x, y;
	int n, k;
	cin >> n >> k;
	int num = 0;//记录未初始化次数
	for (int i = 1; i <= k; i++)
	{
		cin >> x >> y;
		//int型,当尝试访问一个不存在的键,它会自动插入一个新的键并将其关联值初始化为0
		if (y != 0 && mp[y] == 0)
		{
			num++;
		}
		mp[x]++;
	}
	cout << num << endl;
	return 0;
}

三、总结

小tips:

1.科学计数法:100001==1e5+1

2.if (x)等价于if (x!=0)、if (!x)等价于if (x==0)

3.快速判断之前是否存在这个值,应该想到使用map,以int型为例,当尝试访问一个不存在的键,它会自动插入一个新的键并将其关联值初始化为0。

  • 7
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值