蓝桥备赛(第二周)

递归,排序算法和贪心思维

1.汉诺塔

#include<bits/stdc++.h>
using namespace std;
int main()
{
	//2^n-1
	cout<<(unsigned long long)pow(2,64)<<endl;
	return 0;
}

2.数字三角形

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n;
int a[110][110],sum[110][110];
signed main()
{
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=i;j++)
		{
			cin>>a[i][j];
		}
	}
	sum[1][1]=a[1][1];
	for(int i=2;i<=n;i++)
	{
		for(int j=1;j<=i;j++)
		{
			sum[i][j]=a[i][j]+max(sum[i-1][j],sum[i-1][j-1]);
		}
	}
	cout<<max(sum[n][(n+1)/2],sum[n][(n+2)/2])<<endl;
	return 0;
}

3.奇妙变换

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int mod=998244353;

int fun(int x)
{
	if(x<=10)
	{
		return x*(x-1)%mod;
	}
	else
	{
		return 2*x*fun(x-6)%mod;
	}
}
signed main()
{
	int n;
	cin>>n;
	if(n<=10)
	{
		cout<<n*(n-1)%mod<<endl;
	}
	else
	{
		cout<<2*n*fun(n-6)%mod<<endl;
	}
	return 0;
}

4.全排列的价值

#include <iostream>
using namespace std;

const int MOD = 998244353;
const long long inv4 = 748683265; // 4的逆元模998244353

int main() {
    int n;
    cin >> n;
    if (n < 2) {
        cout << 0 << endl;
        return 0;
    }
    long long fact = 1;
    for (int i = 2; i <= n; ++i) {
        fact = fact * i % MOD;
    }
    long long ans = fact * n % MOD;
    ans = ans * (n - 1) % MOD;
    ans = ans * inv4 % MOD;
    cout << ans << endl;
    return 0;
}

5.数正方形

#include<bits/stdc++.h>
#define int long long
using namespace std;
signed main()
{
	// n*n+(n-1)*(n-1)*2+(n-2)*(n-2)*3+..+()+n
	int n;
	cin>>n;
	int ans;
	for(int i=1; i<n; i++)
	{
		ans+=i*(n-i)*(n-i);
		ans%=1000000007;
	}
	cout<<ans;
	return 0;
}

6.高塔登顶方案

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,m,k;
const int mod=1e9+7;
int dp[100010]; //方案数
int sum[100010]; //表示从 dp[0] 到 dp[i] 的累加和
signed main()
{
	cin>>n>>m>>k;
	dp[1]=1;
	sum[1]=1;
	for(int i=2; i<=n; i++) //有序先遍历背包
	{
		int r=max(i-m,0LL); //LL避免类型不一致出问题
		int l=max(i-k,1LL); //方便后面sum[l-1]
		dp[i]=(sum[r]-sum[l-1]+mod)%mod;
		sum[i]=(sum[i-1]+dp[i])%mod;
	}
	cout<<dp[n]<<endl;
	return 0;
}

7.封闭图形个数

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n;
int a[200010];
map<int, int>p;
vector<pair<int,int>>a1;
int fun(int x)
{
	int x1=0;
	while(x>0)
	{
		x1+=p[x%10];
		x/=10;
	}
	return x1;
}

bool cmp(const pair<int, int>& x, const pair<int, int>& y)
{
	if(x.second==y.second)
	{
		return x.first<y.first;
	}
	return x.second<y.second;
}

signed main()
{
	p[1] = 0;
	p[2] = 0;
	p[3] = 0;
	p[5] = 0;
	p[7] = 0;
	p[0] = 1;
	p[4] = 1;
	p[6] = 1;
	p[9] = 1;
	p[8] = 2;
	cin>>n;
	for(int i=0; i<n; i++)
	{
		cin>>a[i];
		a1.push_back({a[i],fun(a[i])});
	}
	sort(a1.begin(),a1.end(),cmp);
	for(int i=0; i<n; i++)
	{
		cout<<a1[i].first<<" ";
	}
	return 0;
}

8.错误票据

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n;
vector<int>a;
signed main()
{
	cin>>n;
	getchar();
	string line;
	while(n--)
	{
		getline(cin,line);
		stringstream ss(line);
		int num;
		while(ss>>num)
		{
			a.push_back(num);
		}
	}
	sort(a.begin(),a.end());
	int m,n; 
	for(int i=0;i<a.size()-1;i++)
	{
		if((a[i]+1)!=a[i+1] && a[i]!=a[i+1]) //断号且非重号情况 
		{
			m=a[i]+1;
		}
		if(a[i]==a[i+1]) //重号 
		{
			n=a[i];
		}
	}
	cout<<m<<" "<<n<<endl;
	return 0;
}

9.训练士兵

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,s;
vector<pair<int,int>>nums;
int sum=0,sum1=0,sign=0;
bool cmp (const pair<int,int> &x,const pair<int,int> &y)
{
	return x.second>y.second;
}
signed main()
{
	cin>>n>>s;
	while(n--)
	{
		int p,c;
		cin>>p>>c;
		nums.push_back({p,c});
	}
	sort(nums.begin(),nums.end(),cmp); //贪心:局部最优多个士兵单次训练(pi+...+pn>s) n之前的单次训练划算
	for(int i=0; i<nums.size(); i++)
	{
		sum+=nums[i].first; 
		if(sum>=s)
		{
			sign=i; //sign之前的单次训练划算,组团训练只考虑训练次数最多士兵花费 
			break;
		}
	}
	for(int i=0; i<sign; i++)
	{
		sum1+=nums[i].first*(nums[i].second-nums[sign].second); //非组团训练花费 
	} 
	sum1+=s*nums[sign].second; //组团训练花费 
	cout<<sum1<<endl; 
	return 0;
}

10.三国游戏

//博弈论:
假设玩家最先拿取武将a,c;计算机因此拿取武将b,d。根据规则,a与b默契值最高,c与d默契值最高
//则b与d的默契值不可能最高,最多为第二高(最高默契被破坏) 即计算机<=玩家,玩家必胜 
//那么,只要找到【第二高的默契值】最高的一对武将,拿取之后便一定胜利。 
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n;
int a[510][510];
int fun(int i)
{
    int b[510];
    for(int j=0; j<n-1; j++)
    {
        b[j]=a[i][j]; //遍历每一列,选取每个武将默契值第二大的另一个武将
    }
    sort(b,b+n-1);
    return b[n-3];
}
signed main()
{
    cin>>n;
    for(int i=0; i<n-1; i++)
    {
        for(int j=i; j<n-1; j++)
        {
            cin>>a[i][j];
            a[j][i]=a[i][j];
        }
    }
    int max1=0;
    for(int i=0; i<n-1; i++)
    {
        max1=max(max1,fun(i)); 
    }
    cout<<1<<endl<<max1<<endl;
    return 0;
}
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n;
int a[100010],b[100010],c[100010];
int w1[100010],w2[100010],w3[100010];
int sum1=0,sum2=0,sum3=0,sign1=-1,sign2=-1,sign3=-1;
signed main()
{
	cin>>n;
	for(int i=0; i<n; i++) cin>>a[i];
	for(int i=0; i<n; i++) cin>>b[i];
	for(int i=0; i<n; i++) cin>>c[i];
	for(int i=0; i<n; i++)
	{
		w1[i]=a[i]-b[i]-c[i];
		w2[i]=b[i]-a[i]-c[i];
		w3[i]=c[i]-a[i]-b[i];
	}
	sort(w1,w1+n,greater<int>()); //存在负数,要使事件最多,应从大加到小
	sort(w2,w2+n,greater<int>());
	sort(w3,w3+n,greater<int>());
	for(int i=0; i<n; i++)
	{
		sum1+=w1[i];
		if(sum1>0)
		{
			sign1=i+1;
		}
		else
		{
			break;
		}
	}
	for(int i=0; i<n; i++)
	{
		sum2+=w2[i];
		if(sum2>0)
		{
			sign2=i+1;
		}
		else
		{
			break;
		}
	}
	for(int i=0; i<n; i++)
	{
		sum3+=w3[i];
		if(sum3>0)
		{
			sign3=i+1;
		}
		else
		{
			break;
		}
	}
	int ans=-1;
	ans=max(max(sign1,sign2),sign3);
	cout<<ans<<endl;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值