NOIP2011普及组复赛解题报告
第一题:数字反转
如果你这道题没得到满分,只能说明一件事:
你题刷的太少哈哈哈!
题解:
#include<cstdio>
#include<cmath>
int main()
{
freopen("reverse.in","r",stdin);
freopen("reverse.out","w",stdout);
int n,i,j,a[10];
bool tf=false,p=false;
scanf("%d",&n);
if(n<0){n=-n;p=true;}
if(n==0)printf("0");
else
{
for(j=0;j<=9;j++)
{if(n>=pow(10,j)&&n<pow(10,j+1))break;}
for(i=0;i<=j;i++)
a[i]=floor((n%(int)(pow(10,i+1)))/(pow(10,i)));
if(p==true)printf("-");
for(i=0;i<=j;i++)
if(!(a[i]==0&&tf==false)){printf("%d",a[i]);tf=true;}
}
fclose(stdin);fclose(stdout);
return 0;
}
思路:
你个指针还看什么思路!!!
第二题:统计单词数
水水水!water
题解:
#include<cstdio>
#include<cstdlib>
#include<cstring>
int ans=2000000000,tot=0,o=0;
char s[110],x[110];
void change()
{
int sl,xl;sl=strlen(s);xl=strlen(x);
for(int i=0;i<sl;i++)
if(s[i]>='A'&&s[i]<='Z')s[i]=s[i]-'A'+'a';
for(int i=0;i<xl;i++)
if(x[i]>='A'&&x[i]<='Z')x[i]=x[i]-'A'+'a';
}
int main()
{
freopen("stat.in","r",stdin);
freopen("stat.out","w",stdout);
scanf("%s",x);
for(int i=1;scanf("%s",s)!=EOF;i++)
{
change();
if(strcmp(s,x)==0){tot++;ans=ans<o?ans:o;}
o+=strlen(s)+1;
}
if(tot!=0)printf("%d %d",tot,ans);
else printf("-1");
fclose(stdin);fclose(stdout);
}
思路:
简单的字符串处理。
第三题:瑞士轮
如果你读不懂题,只能说明你语文不好。
编程实现没难度。
题解:
#include<cstdio>
#include<algorithm>
#define maxn 100000
using namespace std;
int n,r,q;
int a[maxn*2+100],win[maxn+100],lose[maxn+100],s[maxn*2+100],w[maxn*2+100];
bool cmp(int x,int y)
{if(s[x]!=s[y])return s[x]>s[y];return x<y;}
bool MAX(int x,int y)
{if(s[x]!=s[y])return s[x]>s[y];return x<y;}
void merge()
{
int i,j,k;
i=j=1,a[0]=0;
while(i<=win[0]&&j<=lose[0])
if(MAX(win[i],lose[j]))a[++a[0]]=win[i++];
else a[++a[0]]=lose[j++];
while(i<=win[0])a[++a[0]]=win[i++];
while(j<=lose[0])a[++a[0]]=lose[j++];
}
int main()
{
freopen("swiss.in","r",stdin);
freopen("swiss.out","w",stdout);
int i,j,k;
scanf("%d%d%d",&n,&r,&q),n<<=1;
for(i=1;i<=n;i++)a[i]=i;
for(i=1;i<=n;i++)scanf("%d",&s[i]);
for(i=1;i<=n;i++)scanf("%d",&w[i]);
sort(a+1,a+n+1,cmp);
for(i=1;i<=r;i++)
{
win[0]=lose[0]=0;
for(j=1;j<=n;j+=2)
if(w[a[j]]>w[a[j+1]])
{
s[a[j]]++;
win[++win[0]]=a[j];
lose[++lose[0]]=a[j+1];
}
else
{
s[a[j+1]]++;
win[++win[0]]=a[j+1];
lose[++lose[0]]=a[j];
}
merge();
}
printf("%d\n",a[q]);
fclose(stdin);fclose(stdout);
}
思路:
模拟。
第四题:表达式的值
难。
题解:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int mod=10007;
char so[100010],s[100010];
int s1[100010],s0[100010],to,tn,l;
bool have(int p)
{if(p>1&&s[p-1]==')')return 0;return s[p]!='(';}
bool can(char a,char b)
{if(a=='(')return 0;return a!='+'||b!='*';}
void calc()
{
int a0=s0[tn],a1=s1[tn],b0=s0[tn-1],b1=s1[tn-1];
tn--;
if (so[to]=='+')
{
s0[tn]=a0*b0%mod;
s1[tn]=(a1*b1%mod+a1*b0%mod+a0*b1%mod)%mod;
}
else
{
s0[tn]=(a0*b0%mod+a0*b1%mod+a1*b0%mod)%mod;
s1[tn]=a1*b1%mod;
}
to--;
}
int main()
{
freopen("exp.in","r",stdin);
freopen("exp.out","w",stdout);
int i,j,k,m,n,p,q,x,y,z;
scanf("%d%s",&l,s+1);
s[0]='(';s[l+1]=')';
for (i=0;i<=l+1;i++)
{
if(have(i))
{tn++;s0[tn]=s1[tn]=1;}
if (s[i]==')')
{while(so[to]!='(')calc();to--;}
else
{
if(s[i]=='(')so[++to]='(';
else
{
while(to&&can(so[to],s[i]))calc();
so[++to]=s[i];
}
}
}
printf("%d\n",s0[1]);
fclose(stdin);fclose(stdout);
}
思路:
算法类似于表达式运算。
栈。一个符号栈加两个数栈。
总结:
综上所述,
第一至三题,水
第四题,难
noip2011年真题做完了,400分给好评。。。