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;
}