信息模拟赛总结

信息模拟赛总结,难度为noip;

这次最难的第四题我豁然开朗,而第一二三都炸了,加起来也没第四题高,第三名;

我来分析一下这次的考题

第一题:

有很多小朋友在玩无聊的游戏,他们围成一个矩阵,规则是把离自己最近的给淘汰了,直到只剩一人,问谁能最终剩下

cin                                            cout

2                                               1

0 0

0 1

这题代码量还行,放在第一题是因为不用动脑筋,直接模拟就行,但还是只有一人AC,这真是细心大佬啊,

 我的程序(初):

#include<bits/stdc++.h>
using namespace std;
int n,m,k,i,j,b[3];
pair<int,int> a[1001];
int main()
{
cin>>n;
for(i=1;i<=n;i++)
{
scanf("%d%d",&a[i].first,&a[i].second);
}
sort(a+1,a+n+1);
    b[1]=1;j=1;a[n+1].first =100000;a[n+1].second=100000;
for(i=2;i<=n;i+=j)
{
if(i%2!=0)
{
 if(a[i].first+a[i].second-a[b[i]].first-a[b[i]].second<a[i].first+a[i].second-a[i+1].first-a[i+1].second||i>=n)
    {
  b[1]=i;
  j=1;
}
 else
   j=2;
   }
  
}
cout<<b[1];
return 0;

}

修改之后(AC代码)

 

#include<bits/stdc++.h>
using namespace std;
int n,k,m;
double a[1010],b[1010],l,minx;
bool p[1010]={};
int main()
{
	cin>>n;
	for (int i=1;i<=n;i++) cin>>a[i]>>b[i];
	m=n;
	while (m>1)
	{
		for (int i=1;i<=n;i++)
			if (!p[i])
			{
				minx=10000000;
				for (int j=1;j<=n;j++)
				{
					if (i!=j&&!p[j])
					{
						l=sqrt((a[i]-a[j])*(a[i]-a[j])+(b[i]-b[j])*(b[i]-b[j]));
						if (l<minx)
						{
							minx=l;
							k=j;
						}
					}
				}
				m--;
        		p[k]=1;
			}
	}
	for (int i=1;i<=n;i++)
	  if (!p[i]) cout<<i<<endl;
	return 0;
}

第二题

放水壶,单凳双凳,单凳两边,双凳两边。

例子

‘SLLLLSSLL’可以如下所示的放暖壶的位置。* S * L  L *L  L * S * S *L L *

代码

#include<bits/stdc++.h>
using namespace std;
int n,i,j,num=0;
string s;
char c,ca[2502];
int main()
{
   cin>>n>>s;j=1;
   for(i=0;i<n;i++)
   {
     c=s[i];
     if(s[i]=='S')
       {
        ca[j-1]='*';
        ca[j]='S';
        j++;
        ca[j]='*';
        j++;
       }
    else
     if(ca[j-1]=='L')
{
ca[j]='L';
j++;
ca[j]='*';
j++;
} 
  else
    {
      ca[j]='L';
      j++;
    }
}
if(ca[1]=='L')
  num++;
    for(i=1;i<=j;i++)
    {
    if(ca[i]=='S'||ca[i]=='L')
if(ca[i-1]=='*')
   ca[i-1]=='-';
 else
   if(ca[i+1]=='*')
     ca[i+1]='-';
   else
     ca[i]='-';
    }
    for(i=0;i<=j;i++)
 {
  if(ca[i]=='L'||ca[i]=='S')
   num++;
 }    
   cout<<num;
   return 0;

}

第三题:

括号表达式子,一定匹配。

老师高深代码:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
#define rep(i, n) for(int i=0; i<(n); ++i)
#define for1(i,a,n) for(int i=(a);i<=(n);++i)
#define for2(i,a,n) for(int i=(a);i<(n);++i)
#define for3(i,a,n) for(int i=(a);i>=(n);--i)
#define for4(i,a,n) for(int i=(a);i>(n);--i)
#define CC(i,a) memset(i,a,sizeof(i))
#define read(a) a=getint()
#define print(a) printf("%lld", a)
#define dbg(x) cout << #x << " = " << x << endl
#define printarr2(a, b, c) for1(i, 1, b) { for1(j, 1, c) cout << a[i][j]; cout << endl; }
#define printarr1(a, b) for1(i, 1, b) cout << a[i] << ' '; cout << endl
inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; }
inline const int max(const int &a, const int &b) { return a>b?a:b; }
inline const int min(const int &a, const int &b) { return a<b?a:b; }
 
const int N=100005;
const long long MD=12345678910;
int n, q[N], top, inext[N];
long long dfs(int l, int r) {
    int rr=inext[l];
    long long ret=0;
    if(l!=rr-1) ret=(ret+((dfs(l+1, rr-1)<<1)%MD))%MD;
    else if(l==rr-1) ret=(ret+1)%MD;
    if(rr+1<=r) ret=(ret+(dfs(rr+1, r)%MD))%MD;
    return ret;
}
 
int main() {
    read(n);
    for1(i, 1, n) {
        int t=getint();
        if(!t) q[++top]=i;
        else inext[q[top--]]=i;
    }
    print(dfs(1, n));
    return 0;
}

第四题

加加汽油

#include<bits/stdc++.h>
using namespace std;    
long long n,g,b,d;
long long x[50005],c[50005],y[50005],head=1,tail=0,sum=0,ans=0;
struct kkk
 {
   long long d,p;
   
 }a[50005];
 bool myc(kkk xx,kkk yy)
 {
  return xx.d<yy.d;
 }
int main()
{
  cin>>n>>g>>b>>d;
  sum=b;
  for(long long i=1;i<=n;i++)
    cin>>a[i].d>>a[i].p;
  n++;
  a[n].d=d;
  a[n].p=0;
  sort(a+1,a+n+1,myc);
  for(long long i=1;i<=n;i++)
    c[i]=a[i].d-a[i-1].d;
  x[++tail]=b;
  y[tail]=0;
     for(long long i=1;i<=n;i++)
{
         if(sum-c[i]<0)
  {
  cout<<-1;
  exit(0);
  }
         while(c[i])
{
             if(c[i]>=x[head])
  c[i]-=x[head],sum-=x[head],head++;
             else 
  x[head]-=c[i],sum-=c[i],c[i]=0;
       }         
     while(y[tail]>a[i].p&&head<=tail)
      sum-=x[tail],ans-=x[tail]*y[tail],tail--;        
     x[++tail]=g-sum;
     y[tail]=a[i].p;
     ans+=a[i].p*(g-sum);
     sum=g;
    }     
   cout<<ans;
    return 0;

 }

我们可以想象,我们车子的油是可以退回的,也就是只有燃烧的油才会真那么我们每次进站之后,都先将油加满,等到到了下一个加油站发现了更便宜的油,我们把贵的油都退了,再把便宜的油加满油箱,这样就可以用单调队列实现这道题;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值