【题目链接】
http://codeforces.com/contest/298
这场比赛做的还可以,1hA了两道题,2h的时候做出来第三道。没有想到这场出的都是想法题。尤其是E题,确实是很考构造能力的。
官方题解在此,十分清楚。
http://codeforces.com/blog/entry/7437
下面是代码:
A.容易想到脚步方向的排布只有三种,陈题。
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin>>n;
char road[1000+100];
cin>>road;
int L=0,R=0;
for( int i=0;i<n;i++ )if( road[i]!='.' )
{
if( L==0 )L=i;
R=i;
}
// cout<<L<<" "<<R<<endl;
if( road[L]=='R' )
{
int pos=0,i;
for( i=L; i<=R; i++ )if( road[i]=='L' ){ pos=i; break; }
if(pos){ cout<<L+1<<" "<<pos<<endl; }
else cout<<L+1<<" "<<R+2<<endl;
}
else if( road[L]=='L' )
{
cout<<L+1<<" "<<L<<endl;
}
return 0;
}
B.模拟一下就好了
#include<bits/stdc++.h>
using namespace std;
int all[5]={0};
int main()
{
int t,Sx,Sy,Ex,Ey,tx,ty;
cin>>t>>Sx>>Sy>>Ex>>Ey;
tx=Ex-Sx;
ty=Ey-Sy;
char str[100000+100];
scanf("%s",&str[1]);
for( int i=1; i<=t; i++ )
{
if( str[i]=='E' )all[1]++; //水平方向
else if( str[i]=='S' )all[2]--;
else if( str[i]=='W' )all[3]--;
else all[4]++;
}
if( tx<=0 && ty<=0 )
{
for( int i=1; i<=t; i++ )
{
if( str[i]=='W' && tx<0 )tx++;
else if( str[i]=='S' && ty<0 )ty++;
if( tx==0 && ty==0 ){ cout<<i<<endl; return 0; }
}
}
else if( tx<=0 && ty>=0 )
{
for( int i=1; i<=t; i++ )
{
if( str[i]=='W' && tx<0 )tx++;
else if( str[i]=='N' && ty>0 )ty--;
if( tx==0 && ty==0 ){ cout<<i<<endl; return 0; }
}
}
else if( tx>=0 && ty<=0 )
{
for( int i=1; i<=t; i++ )
{
if( str[i]=='E' && tx>0 )tx--;
else if( str[i]=='S' && ty<0 )ty++;
if( tx==0 && ty==0 ){ cout<<i<<endl; return 0; }
}
}
else
{
for( int i=1; i<=t; i++ )
{
if( str[i]=='E' && tx>0 )tx--;
else if( str[i]=='N' && ty>0 )ty--;
if( tx==0 && ty==0 ){ cout<<i<<endl; return 0; }
}
}
cout<<-1<<endl;
return 0;
}
C.比较巧妙的构造,应当学习。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int main()
{
string a,b;
cin>>a>>b;
int lenA=a.length();
int lenB=b.length();
int A1=0,B1=0;
for( int i=0; i<lenA; i++ )if( a[i]=='1' )A1++;
for( int j=0; j<lenB; j++ )if( b[j]=='1' )B1++;
if( A1&1 )A1++;
if( A1>=B1 )cout<<"YES\n";
else cout<<"NO\n";
return 0;
}
D.只要想到可以贪心,那么推理就不难。不过难就难在敢于贪心的去想这道题目。CF果然是比较靠感觉的。
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,m,k;
int a[100000+10],b[100000+10];
cin>>n>>m>>k;
for( int i=1; i<=n; i++ )cin>>a[i];
for( int j=1; j<=m; j++ )cin>>b[j];
if( n>m ){ cout<<"YES\n"<<endl; return 0; }
sort( a+1,a+1+n );
sort( b+1,b+1+m );
if( n==m )
{
for( int i=n ;i>=1; i-- )
{
//if( a[i]<b[i] ){ cout<<"NO\n"; return 0; }
if( a[i]>b[i] ) { cout<<"YES\n"; return 0; }
}
cout<<"NO\n";
}
else
{
int i=n, j=m;
while( i && j )
{
if( a[i]>b[j] ){ cout<<"YES\n"; return 0; }
i--; j--;
}
cout<<"NO\n";
}
return 0;
}
E.从这道题目可以学会如何把一个看似复杂的问题简化,形象化。这里仍然是一个贪心的思想。不过边界情况的考虑显然是需要下一番功夫的。虽然看了题解,还是WA了四发,修正了一些思维上的错误,终于A掉了这道题。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+100;
struct point
{
int pos,s,a,b;
}P[maxn];
bool cmp1( point A, point B ){ return A.s<B.s; }
bool cmp2( point A, point B ){ return A.pos<B.pos; }
int main()
{
int N; cin>>N;
for( int i=0; i<N; i++ ) { cin>>P[i].s; P[i].pos=i; }
sort( P,P+N,cmp1 );
for( int i=0; i<N; i++ )
{
if( i<N/3 ) { P[i].a=i; P[i].b=P[i].s-i; }
else if( i<N*2/3 ) { P[i].b=i; P[i].a=P[i].s-i; }
else { P[i].b=N-1-i; P[i].a=P[i].s-P[i].b; }
}
sort( P,P+N,cmp2 );
cout<<"YES\n";
for( int i=0; i<N; i++ )
{
if( i==N-1 )cout<<P[i].a<<endl;
else cout<<P[i].a<<" ";
}
for( int i=0; i<N; i++ )
{
if( i==N-1 )cout<<P[i].b<<endl;
else cout<<P[i].b<<" ";
}
return 0;
}