信息模拟赛总结,难度为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;
}
我们可以想象,我们车子的油是可以退回的,也就是只有燃烧的油才会真那么我们每次进站之后,都先将油加满,等到到了下一个加油站发现了更便宜的油,我们把贵的油都退了,再把便宜的油加满油箱,这样就可以用单调队列实现这道题;