Hello 2022

本文介绍了两个算法问题的解决方案。第一个问题是关于棋盘上皇后的稳定排列,当皇后数量超过棋盘半径时,无法排列;否则,按特定规则放置。第二个问题涉及在整数商店中购买整数,目标是获取最多不同整数,通过分析不同段的价格和长度,确定最优策略。
摘要由CSDN通过智能技术生成

A. Stable Arrangement of Rooks

B. Integers Shop

C. Hidden Permutations

D. The Winter Hike

F. Strange Instructions

G. Weighted Increasing Subsequences

H. Trains and Airplanes

I. Two Sequences


A. Stable Arrangement of Rooks

分析:
新年第一发,肯定不难。一道简单思维题。首先,不难发现,当k>(n+1)/2时,最后的结果肯定是-1。然后对于其他情况,只需要对于一个二维字符数组,先全部初始化为’.‘,然后从1开始遍历k个字符,将第2 * i-1行第2*i-1列的字符赋值为’R’即可

AC代码:

#include<bits/stdc++.h>
using namespace std;
int main(){
	int t;cin>>t;
	while(t--){
		int n,k;cin>>n>>k;
		char str[100][100];
		for(int i=1;i<=40;i++)
		   for(int j=1;j<=40;j++) str[i][j]='.';
		if(k>(n+1)/2) cout<<-1<<endl;
		else{
				for(int j=1;j<=n&&k>0;j+=2,k--) str[j][j]='R';
				for(int i=1;i<=n;i++){
					for(int j=1;j<=n;j++) cout<<str[i][j];
						cout<<endl;
				}
		}
	}
	return 0;
}

B. Integers Shop

分析:
设L是最小整数,R是最大整数。然后很容易知道,他将得到L和R之间的所有整数。
因为Vasya想要最大化他将得到的整数的数量,他应该在商店中购买最小和最大的整数。它们可以出现在同一段中,也可以出现在不同的段中。需要注意的是,如果它们出现在同一段中,那么它就是最长的那段。
让我们一个一个地添加段来购物,并维护以下六个值:
1.商店中最小的整数和包含它的最便宜段的成本。
2.商店中最大的整数和包含它的最便宜段的成本。
3.最长段的长度和这些段中最便宜段的代价。

很容易看到,当我们添加新的段时,这个值只能通过新段的参数来更新。
时间复杂度为O(n)
AC代码:

#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
const int maxn=1e5+10;
int l[maxn],r[maxn],c[maxn];
int main(){
	int t;cin>>t;
	while(t--){
		int mL=INF,mR=0,cL=INF,cR=INF,mlen=0,mc=0;
		int n;cin>>n;
	    for(int i=1;i<=n;i++){
	    	int l,r,c;
	    	cin>>l>>r>>c;
	    	if(l<mL) mL=l,cL=c;
	    	if(l==mL) cL=min(cL,c);
	    	if(r>mR) mR=r,cR=c;
	    	if(r==mR) cR=min(cR,c);
	    	if(mlen<r-l+1) mlen=r-l+1,mc=c;
	    	if(mlen==r-l+1) mc=min(mc,c);
	    	int ans=cL+cR;
	    	if(mlen==mR-mL+1) ans=min(ans,mc);
	    	cout<<ans<<endl;
		}
	}
	return 0;
}

D. The Winter Hike

分析:
一道不难的思维题,但是蒻蒻却没有写出来。我们把整个图看成四部分,左上部分,左下部分,右上部分,右下部分
首先右下部分也就是第n+1行到第2 * n行,第n+1列到第2 * n列的花费肯定是要在最后结果ans里的,所以结果ans需要加入这部分每一个格子的花费。对于其他部分的花费,我们只需要分析四个点即点(1,n),(1,1),(n,1),(n,n)。因为这四个点可能达到左下角或者右上角的八个地方即点(1,n+1),(1,2 * n),(n,n+1),(n,2 * n),(n+1,1),(n+1,n),(2 * n,1),(2 * n,n)。而这8个点中任意一点都可以通过一次移动从而到达右下角部分。然后仔细观察不难发现,我们左上部分的n * n个朋友都可以无需花费移动到左上部分那四个点,然后再通过n*n次利用这8个点中的某一个点便可以以最小的花费得到最后结果。所以最终结果便是ans加上这8个点中最小花费的那个点的花费minn
需要注意的是,本题需要开long long,不然结果会溢出。

AC代码:

#include <iostream>
using namespace std;
#define INF 0x7fffffff
void solve() {
    long long n,ans=0; cin >> n;
    long long a[3000][3000];
    for (int i = 1; i <= 2 * n; i++) {
        for (int j = 1; j <= 2 * n; j++) {
            cin>>a[i][j];
            if (i > n && j > n) ans += a[i][j];
        }
    }
    long long minn = INF;
    minn = min(minn, a[n][n + 1]);
    minn = min(minn, a[n + 1][n]);
    minn = min(minn,a[n + 1][1]);
    minn = min(minn, a[2 * n][1]);
    minn = min(minn, a[2 * n][n]);
    minn = min(minn, a[1][n + 1]);
    minn = min(minn, a[1][2 * n]);
    minn = min(minn, a[n][2 * n]);
    cout << ans+minn << endl;
}
int main()
{
    iostream::sync_with_stdio(false);
    int t; cin >> t;
    while (t--) {
        solve();
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

&が&

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值