【Educational Cf Round 125 】A—D

A Integer Moves

题意:略
题解:一共就三种情况,具体略(
需要注意的是sqrt()返回的并不是整型,记得前面加(Int)

#include <bits/stdc++.h>
using namespace std;
const int maxn=2e5+7;
#define sc scanf
#define pr printf
#define ll long long
#define mod 998244353 
#define INT INT_MAX
ll dp[maxn][5];
int main() {
    int t;
    cin>>t;
    while(t--){
    	int x,y;cin>>x>>y;
		int k=(int)sqrt(x*x+y*y)*(int)sqrt(x*x+y*y);
		//cout<<k<<"aaaa"<<(x*x+y*y)<<endl;
    	if(x==y&&x==0)cout<<0<<endl;
    	else if(k==(x*x+y*y))cout<<1<<endl;
    	else cout<<2<<endl;
	}
	return 0;
}

B XY Sequence

题意:略
题解:个人人为这个比A更清晰,模拟一下过程即可。能加则加,否则减。这样可尽最大可能加最多。

#include <bits/stdc++.h>
using namespace std;
const int maxn=2e5+7;
#define sc scanf
#define pr printf
#define ll long long
#define mod 998244353 
#define INT INT_MAX
ll dp[maxn][5];
int main() {
    int t;
    cin>>t;
    while(t--){
        ll n,b,x,y;sc("%lld%lld%lld%lld",&n,&b,&x,&y);
        ll sum=0;
        ll now=0;
        for(int i=0;i<n;i++)
		{
		if(now+x<=b)now+=1ll*x;
		else now-=1ll*y;
		sum+=now;
		}
		pr("%lld\n",sum);
        
	}
	return 0;
}

C Bracket Sequence Deletion

题意:两种方法消前缀,且题目说了the shortest prefix,即最短前缀。
而消前缀两种方法:
1.匹配 2.回文

题解:
这题乍一看立马想到括号匹配,仔细一想被带歪了
因为一共就几种情况:(我觉得括号很能迷惑人,改成字符就很恨很清楚)
1.( )可以消去——匹配
2.( ( 可以消去——aa
3. ) )可以消去——bb
4. )( 待定
)( 看作ba,可知无论中间的a有多少,找到一个b即可回文,即baaaaaab,如果没有,则不可能再消去了。

#include <bits/stdc++.h>
using namespace std;
const int maxn=2e5+7;
#define sc scanf
#define pr printf
#define ll long long
#define mod 998244353 
#define INT INT_MAX
int main() {
    int t;
    cin>>t;
    while(t--){
        int n;sc("%d",&n);
        string s;cin>>s;
        int ans=0;int i;
        for(i=0;i<s.size()-1;){
        	if(s[i]==')'&&s[i+1]=='('){
        		int c=i;
        		i+=2;
        		while(i<s.size()){
        			if(s[i]!=')') i++;
        			else break;
				}
				if(i<s.size()&&s[i]==')'){
					ans++,i++;
				}
				else {
					i=c;goto ans;
				}
			}
			else {
				ans++;
				i+=2;
			}
		}
        ans:pr("%d %d\n",ans,s.size()-i);
	}
	return 0;
}

D For Gamers. By Gamers.

题意:
士兵n,拥有金币C;
对n个士兵,每一个拥有花费:ci,伤害:di,生命hi。
怪物m;
对m个怪物,每一个拥有伤害:di,生命hi。
求,对m种怪物的最少金币杀死方案。
需注意:
1.Monocarp chooses one type of units
它每次只能选择一组士兵,可无限次重复消费ci
2.not once per second
不是论秒判断胜负,这里需要结合示例分析

题解:
可以看出:需满足
x为选择x次
(不用数学工具编了,直接看吧
在这里插入图片描述
请添加图片描述
存下dixhi-1的数组,然后二分查找满足题意的。

具体实现注意
一个数组di,hi
一个数组储存满足题意的dixhi-1
二分用到的数组,需要对第二个数组作处理:从前到后求前缀最大值

注意定义为ll会减少很多麻烦,不然多处都要特殊处理,容易遗忘。

#include<bits/stdc++.h>
#define ll long long
#define sc scanf
#define pr printf
using namespace std;
const ll maxn=1e6+10;
ll ci[maxn];
ll k[maxn];
int main()
{
     int n,C;cin>>n>>C;
	 ll c,d,h;
     for(int i=0;i<n;i++){
     sc("%lld%lld%lld",&c,&d,&h);
     ci[c]=max(ci[c],h*d);
     }
     for(int i=1;i<=C;i++)//+1????
     	for(int j=i;j<=C;j+=i)
     	   k[j]=max(k[j],(j/i)*ci[i]-1);
      for(int i=1;i<=C;i++)k[i]=max(k[i],k[i-1]);
     int m;cin>>m;
     while(m--){
     	sc("%lld%lld",&c,&h);
     	ll x=c*h;
     	int ans=lower_bound(k,k+C+1,x)-k;
     	if(ans>C)pr("-1\n");
     	else pr("%d ",ans);
	 }
	 pr("\n");
     
 return 0;
}

【写在后面的碎碎念】
这题刚看到的时候,觉得有点像背包?但是因为注意1又否定。
n,m的范围是3e5,怎么莽怎么错,也想不到优化。
然后想,那会是每一组的值确定,例如dh相乘什么的?然后再二分?
但是应该是交叉的关系,怎么可能是这样。
遂放弃。
于是发现是自己数学不好()

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值