思维题训练(二)

G.Skibidus and Fanum Tax (easy version)

题目链接:Problem - 2065C1 - Codeforces


题目解析:

        题中给出一个数组a和一个单位为1的数组b,在这里我直接把它当成一个int类型的数。数组里的每个数都可以选择执行一次b-a[i],如果最后这个序列可以是非递减的,就输出YES,否则输出NO。


解题思路:

        对每个数的两边进行判断:如果它比它的左边小而且操作完之后不必它小,那么就可以进行一次操作,或者如果它比它的右边大而且操作完之后不必它大,也要进行一次操作。等整个序列操作完之后进行遍历,判断它是不是一个非递减序列。


AC Code: 

#include <bits/stdc++.h>
using namespace std;
const int N = 1e6;
int t,n,m,b; 
int a[N];
int main()
{
	cin >> t;
	while(t--)
	{
		cin >> n >> m;
		for(int i=1; i<=n; i++) cin >> a[i];
		cin >> b;
		a[0]=(int)-1e9;
		int flag=1;
		for(int i=1;i<=n;i++)
		{
			if(b-a[i]<=a[i]&&b-a[i]>=a[i-1])
				a[i]=b-a[i];
			
			else if(b-a[i]>=a[i-1]&&a[i]<a[i-1]) 
				a[i]=b-a[i];
			
			if(a[i]<a[i-1])
			{
				flag=0;
				break;
			}
		}
		if(!flag) cout << "NO" << endl;
		else cout << "YES" << endl;
	}
	return 0;
}

B.Scale

题目链接:Problem - 1996B - Codeforces 


题目解析:

        有一个n*n的格子,需要将他缩小k倍(k一定是n的因子),每个缩小后的每一小块都和原来k*k的块的值相等,请输出缩小后的格子。


解题思路:

        在遍历整个网格的时候,由于每个k*k的块值都是一样的,只用输出一个数就行了。所以每次行和列都要跳k个,这样的话直接输出就可以了。


AC Code:

#include <bits/stdc++.h>
using namespace std;
const int N = 1e4+1;
int t;
int n,k;
char s[N][N];
int main()
{
	cin >> t;
	while(t--)
	{
		cin >> n >> k;
		for(int i=1; i<=n; i++)
			for(int j=1; j<=n; j++)
				cin >> s[i][j];

		for(int i=1; i<=n; i+=k)
		{
			for(int j=1; j<=n; j+=k)
				cout << s[i][j];
			cout << endl;
		}
	}
	return 0;
}

E.合并果子

题目链接:P1090 [NOIP 2004 提高组] 合并果子 - 洛谷 


题目解析:

        首先输入一个数,可以看成一共有n堆果子,要把这n堆果子合并成1堆果子,每个果子会消耗1点体力,问合并成一堆果子所需要最少的体力是多少


解题思路:

        因为要使合并所需要的体力值最小,肯定要使合并时的那一堆永远是当前状态下最小的,那么这个时候就需要用到优先队列(小顶堆)了。每次将最上边两个数相加,模拟合并,用ans记录,并将此时的重量放入队列,直到最后队列里只剩一个元素。


AC Code:

#include <bits/stdc++.h>
using namespace std;
int n,x,s,ans;
int main()
{
	priority_queue<int, vector<int>, greater<int>> q;
	cin >> n;
	for(int i=1; i<=n; i++)
	{
		cin >> x;
		q.push(x);
	}
	while(q.size()>1)
	{
		s=0;
		s+=q.top();
		q.pop();
		s+=q.top();
		q.pop();
		ans+=s;
		q.push(s);
	}
	cout << ans;
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值