这次NOIP2016普及组我认为前三题都很简单就只有第四题稍微有点难度,所以还有待提高。
1.pencil
惊天大水题[堪比1000题(a+b problem)]开始还以为是完全背包,读完题后发现只有3种铅笔而且只能买一种(震惊),这就完了?
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,a,b,i,k,ans;
int main()
{
freopen("pencil.in","r",stdin);
freopen("pencil.out","w",stdout);
scanf("%d",&n);
scanf("%d %d",&a,&b);
ans=n/a*b;
if(n%a!=0)
ans=ans+b;
for(i=1;i<=2;i++)
{
scanf("%d %d",&a,&b);
k=n/a*b;
if(n%a!=0)
k=k+b;
ans=min(ans,k);
}
printf("%d",ans);
fclose(stdin);
fclose(stdout);
return 0;
}
2.date
我当时看到这道题时本来想靠每个位置有可能的个数来做的(如20000101到20100101个位只能为2),但是后来想了想,这样可能比直接一天一天的加 错的几率还要大,所以我就选择了直接模拟。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int a[4],b[4],i,j,k,y[30]={0,31,28,31,30,31,30,31,31,30,31,30,31},ans;
bool check(int x,int y,int z)
{
if(x/1000==z%10&&x/100%10==z/10&&x/10%10==y%10&&x%10==y/10)
return 1;
return 0;
}
int main()
{
freopen("date.in","r",stdin);
freopen("date.out","w",stdout);
scanf("%4d%2d%2d %4d%2d%2d",&a[1],&a[2],&a[3],&b[1],&b[2],&b[3]);
for(i=a[1];i<=b[1];i++)
{
for(j= i==a[1]?a[2]:1;j<=12&&(i<b[1]||j<=b[2]);j++)
{
if(j==2&&i%4==0&&(i%100!=0||i%400==0))
y[2]=29;
else
y[2]=28;
for(k= (i==a[1]&&j==a[2])?a[3]:1 ;k<=y[j]&&(i<b[1]||j<b[2]||k<=b[3]);k++)
{
if(check(i,j,k))
{
ans++;
}
}
}
}
printf("%d",ans);
fclose(stdin);
fclose(stdout);
return 0;
}
3.port
因为我看到还会有乘船(cch!)离开所以就想到了用队列,首先用一个数组存每个国家的人数,每当有新的人加入就放入队列(附上时间)和数组(加的是人不是cch乘船),然后如果一个国家的人数从0变到有,ans++;然后检查队列的队首如果那个人超过了一天,就把他拿出来(可怜的cch),如果一个国家的人数从有变为0就ans- -;然后每输出ans就行了。(cch完了!)
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
int n,i,j,t,p,k,ans,a[100005];
struct node
{
int x,t;
};
queue<node> q;
int main()
{
freopen("port.in","r",stdin);
freopen("port.out","w",stdout);
node hh;
node yhn;
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%d %d",&t,&k);
while(!q.empty())
{
yhn=q.front();
if(yhn.t<=t-86400)
{
q.pop();
a[yhn.x]--;
if(a[yhn.x]==0)
ans--;
}
else
break;
}
for(j=1;j<=k;j++)
{
scanf("%d",&p);
if(a[p]==0)
{
ans++;
a[p]++;
hh.x=p;
hh.t=t;
q.push(hh);
}
else
{
a[p]++;
hh.x=p;
hh.t=t;
q.push(hh);
}
}
printf("%d\n",ans);
}
fclose(stdin);
fclose(stdout);
return 0;
}
4.magic
这到题是普及组最难的一道我用暴力骗了85,85分代码如下:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int i,j,k,n,m,b[15005],omg,hjb,is,hh[15005][5],a[40005];
int main()
{
freopen("magic.in","r",stdin);
freopen("magic.out","w",stdout);
scanf("%d %d",&n,&m);
for(i=1;i<=m;i++)
{
scanf("%d",&a[i]);
b[a[i]]++;
}
for(i=1;i<=n;i++)
{
if(b[i])
{
for(j=i+1;j<=n;j++)
{
omg=j-i;
if(b[j]&&omg%2==0)
{
for(k=j+3*(j-i)+1;k<=n;k++)
{
is=omg/2+k;
if(b[k]&&b[is])
{
hjb=b[i]*b[j]*b[k]*b[is];
hh[i][1]=hh[i][1]+(hjb/b[i]);
hh[j][2]=hh[j][2]+(hjb/b[j]);
hh[k][3]=hh[k][3]+(hjb/b[k]);
hh[omg/2+k][4]=hh[omg/2+k][4]+(hjb/b[is]);
}
}
}
}
}
}
for(i=1;i<=m;i++)
printf("%d %d %d %d\n",hh[a[i]][1],hh[a[i]][2],hh[a[i]][3],hh[a[i]][4]);
fclose(stdin);
fclose(stdout);
return 0;
}
总之这次普及很水。(我是说前3题)(是不是要被cch打呀(第3题))