代码源week5

T1:A-B数对A-B 数对 - 题目 - Daimayuan Online Judge

思路:

首先C是已知的,将A-B=C转换为A-C=B,答案就是B在输入的数组中出现的次数之和

由于原数组的数据范围是2^30只能开map

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int n,c,a[200005];
map<int,int> m;
int main()
{
	cin>>n>>c;
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		m[a[i]]++;//记录原数组中每个数字出现的次数
		a[i]-=c;//将A-B=C转换为A-C=B,然后将Bi记录下来
	}
	int ans=0;
	for(int i=1;i<=n;i++){
		if(m[a[i]])ans+=m[a[i]];//统计答案
	}
	cout<<ans<<endl;
	return 0;
}

T2:数位计算数位计算 - 题目 - Daimayuan Online Judge

思路:

显然是一个等差数列求和的例子,要找好首项和尾项,以及项数,然后注意数据范围,先对首项与尾项之和取模,以及项数取模,然后再利用等差数列前n项和计算。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll mod=998244353;
ll n;
int main()
{
	cin>>n;

	int cnt=0;
	long long now=10,ans=0;
	while(now<=n){
		ll a=(now-now/10+1)%mod,b=(now-now/10)%mod;//a:首项与末项之和,b:项数
		ans=(ans+(a*b/2))%mod;//等差数列求和
		now*=10;
	}
	now/=10;
	ll a=(1+n-now+1)%mod,b=(n-now+1)%mod;
	long long last=a*b/2;
	ans=(ans+last)%mod;
	cout<<ans<<endl;;
	return 0;
}

T3:新国王游戏新国王游戏 - 题目 - Daimayuan Online Judge

思路:

典型的贪心问题,考虑第i个人和第i+1个人的位置关系,得到最优方案:a.r*(b.l-1)>b.r*(a.l-1)

#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
int n;
struct dot{
	int l,r;
}d[1000009];
bool cmp(dot a,dot b){
	return a.r*(b.l-1)>b.r*(a.l-1);//按照这种排序
}
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++)scanf("%d%d",&d[i].l,&d[i].r);
	sort(d+1,d+1+n,cmp);
	long long now=d[n].l,ans=d[n].r; 
	for(int i=n-1;i>=1;i--)
	{
		ans=(ans+d[i].r*now)%mod;
		now=(now*d[i].l)%mod;
	}
	cout<<ans<<endl;
	return 0;
}

T4:Lusir的游戏Lusir的游戏 - 题目 - Daimayuan Online Judge

思路:

由于答案是单调的,采用二分答案,二分能量值,然后判断一下边界:当前的能量大于10e5,直接可以通过所有的。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int MAX=1e5+10;
ll h[MAX],n;

bool check(ll x){
	ll now=x;
	for(int i=1;i<=n;i++){
		if(h[i]>now)now-=(h[i]-now);
		else now+=(now-h[i]);
		if(now>1e5)return 1;//边界判断
		if(now<0)return 0;
	}
	return 1;
}

int main()
{
	cin>>n;
	ll mm=-1;
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&h[i]);
	}
	ll l=0,r=1e5;
	while(l<=r){//二分答案

		ll mid=(l+r)/2;
		if(check(mid)){
			r=mid-1;
		}
		else l=mid+1;
	}
	cout<<l<<endl;
 	return 0;
}

T5:BFS练习1BFS练习1 - 题目 - Daimayuan Online Judge

思路:

利用bfs的广度方向搜索的特性,第一次到到或达到某个数,显然是最少步数。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int MM=1e5+5;
int n,m,a[MM];
int s[MM+1000],vis[MM+1000];

struct num{
	int x,step;
};

queue<num> q;
void BFS()
{
	q.push({n,0});vis[n]=1;
	while(q.size()){
		num p=q.front();q.pop();
		int now=p.x+1;
		if(!vis[now]&&now<MM){
			vis[now]=1;
			s[now]=p.step+1;
			q.push({now,p.step+1});
		}
		now=p.x*2;
		if(!vis[now]&&now<MM){
			vis[now]=1;
			s[now]=p.step+1;
			q.push({now,p.step+1});
		}
		now=p.x*3;
		if(!vis[now]&&now<MM){
			vis[now]=1;
			s[now]=p.step+1;
			q.push({now,p.step+1});
		}
		now=p.x-1;
		if(!vis[now]&&now<MM){
			vis[now]=1;
			s[now]=p.step+1;
			q.push({now,p.step+1});
		}
	}
	
}
int main()
{
	cin>>n>>m;
	BFS();
	for(int i=1;i<=m;i++){
		int x;scanf("%d",&x);
		printf("%d ",s[x]);
	}


 	return 0;
}



T6:碰撞2碰撞2 - 题目 - Daimayuan Online Judge

思路:

显然对于这个碰撞只有唯一一种可能:就是同一行的情况下(y一样),然后x小的向右走,x大的向左走,就会碰到。

这样就可以对这个结构体按x为第一关键字排序,vis【i】标记对应行是否出现了x小的向右走,当这一行出现x大的向左走,且vis[i]==1,就会碰到。

#include<bits/stdc++.h>
#define ll long long
using namespace std;


int n;
map<int,int> vis;
struct dot{
	int x,y;
	char dir;
}d[200005];
bool cmp(dot a,dot b){
	if(a.y==b.y)return a.x<b.x;
	else return a.y<b.y;
}
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++)cin>>d[i].x>>d[i].y;
	for(int i=1;i<=n;i++)cin>>d[i].dir;
	sort(d+1,d+1+n,cmp);
	/*for(int i=1;i<=n;i++){
		cout<<"pos: "<<d[i].x<<' '<<d[i].y<<" direction: "<<d[i].dir<<endl;
	}*/
	for(int i=1;i<=n;i++){
		if(d[i].dir=='R')vis[d[i].y]=1;
		if(d[i].dir=='L'&&vis[d[i].y]){
			cout<<"Yes"<<endl;
			return 0;
		}
	}
	cout<<"No"<<endl;
 	return 0;
}



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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值