您的位置:首页 > 其它

2016.1.14 集训第一天 OI

2017-01-14 14:30 232 查看
内容:  队列(queue)  树(tree)

习题

上午

奇怪的电梯(lift)

产生数(produce)

家庭问题(family)

合并果子(fruit)

AK系列(广搜几乎还给斯砍福了,表示抄代码了

)

代码如下

奇怪的电梯(lift)

#include <ctime>
#include <cmath>
#include <cstdio>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define re return
#define s(a)  sizeof(a)
#define maxx(a,b,c) max(max(a,b),c)
#define minx(a,b,c) min(min(a,b),c)
#define up(i,m,n) for(int i=m;i<=n;i++)
#define down(i,m,n) for(int i=n;i>=m;i--)
using namespace std;
const int MAXN=205;
int a[MAXN],n,ne=0,A,B;
int f[MAXN],s[MAXN];
bool flag[MAXN];
inline int print(int x)
{
int ans=0;
while(f[x])
{
ans++;
x=f[x];
}
return ans;
}
void bfs()
{
memset(flag,0,s(flag));
f[1]=0, s[1]=A, flag[A]=1;
int h=0, t=1;
do
{
h++;
for (int j=-1;j<=1;j+=2)
{
int x1=s[h]+j*a[s[h]];
if(x1>0&&x1<=n&&flag[x1]==0)
{
t++;
s[t]=x1;
f[t]=h;//save father;
flag[x1]=1;
if(x1==B)
{
printf("%d\n",print(t));
return;
}
}
}
}while(h<t);
cout<<"-1"<<endl;
}
int main()
{
freopen("lift.in","r",stdin);
freopen("lift.out","w",stdout);
cin>>n>>A>>B;
if (A==B)
{
cout<<"0"<<endl;
re 0;
}
while(scanf("%d",&a[++ne])&&ne<n);
bfs();
return 0;
}

产生数(produce)

#include <ctime>
#include <cmath>
#include <cstdio>
#include <string>
#include <cstring>
#include <stack>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define re return
#define s(a)  sizeof(a)
#define maxx(a,b,c) max(max(a,b),c)
#define minx(a,b,c) min(min(a,b),c)
#define up(i,m,n) for(int i=m;i<=n;i++)
#define down(i,m,n) for(int i=n;i>=m;i--)
using namespace std;

const int MAXN=10005;
int flag[MAXN],father[MAXN],state[MAXN],n,k,num[10],chage[15][15];
void bfs()
{
int head=0,tail=1,tot=0;
state[tail]=n;
flag
=1;
do
{
head++;
for(int j=1;j<=9;j++)
{
num[1]=state[head]/1000;
num[2]=state[head]%1000/100;
num[3]=state[head]%100/10;
num[4]=state[head]%10;
if(chage[num[1]][j]==1&&flag[j*1000+num[2]*100+num[3]*10+num[4]]==0)
{
tail++;
state[tail]=j*1000+num[2]*100+num[3]*10+num[4];
father[tail]=head;
flag[j*1000+num[2]*100+num[3]*10+num[4]]=1;
}
if(chage[num[2]][j]==1&&flag[num[1]*1000+j*100+num[3]*10+num[4]]==0)
{
tail++;
state[tail]=num[1]*1000+j*100+num[3]*10+num[4];
father[tail]=head;
flag[num[1]*1000+j*100+num[3]*10+num[4]]=1;
}
if(chage[num[3]][j]==1&&flag[num[1]*1000+num[2]*100+j*10+num[4]]==0)
{
tail++;
state[tail]=num[1]*1000+num[2]*100+j*10+num[4];
father[tail]=head;
flag[num[1]*1000+num[2]*100+j*10+num[4]]=1;
}
if(chage[num[4]][j]==1&&flag[num[1]*1000+num[2]*100+num[3]*10+j]==0)
{
tail++;
state[tail]=num[1]*1000+num[2]*100+num[3]*10+j;
father[tail]=head;
flag[num[1]*1000+num[2]*100+num[3]*10+j]=1;
}
}
}while(head<tail);
for(int i=1;i<=10000;i++)
tot+=flag[i];
printf("%d\n",tot);
}
int main()
{
freopen("produce.in","r",stdin);
freopen("produce.out","w",stdout);
memset(chage,sizeof(chage),0);
scanf("%d%d",&n,&k);
for(int i=1;i<=k;i++)
{
int x1,x2;
scanf("%d%d",&x1,&x2);
chage[x1][x2]=1;
chage[x2][x1]=1;
}
bfs();
return 0;
}


家庭问题(family)

#include <ctime>
#include <cmath>
#include <cstdio>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define re return
#define s(a)  sizeof(a)
#define maxx(a,b,c) max(max(a,b),c)
#define minx(a,b,c) min(min(a,b),c)
#define up(i,m,n) for(int i=m;i<=n;i++)
#define down(i,m,n) for(int i=n;i>=m;i--)
using namespace std;
const int MAXN=105;
int f[MAXN],a[MAXN],x[10005],y[10005],used[MAXN],c,t,k,i,j,tot,n,m,num;//f[i] i号家庭个数;a[i] 第i个人所属家庭;
void init()
{
memset(f,0,sizeof(f));
scanf("%d%d",&n,&k);
for(i=1;i<=k;i++)
{
scanf("%d%d",&x[i],&y[i]);
used[x[i]]=1;used[y[i]]=1;
if(a[x[i]]==0&&a[y[i]]==0)
{
f[++t]=2;tot++;num++;
a[x[i]]=t;a[y[i]]=t;
}
else if(a[x[i]]!=0&&a[y[i]]==0)
{
f[a[x[i]]]+=1;
a[y[i]]=a[x[i]];
}
else if(a[x[i]]==0&&a[y[i]]!=0)
{
f[a[y[i]]]+=1;
a[x[i]]=a[y[i]];
}
else if(a[x[i]]!=a[y[i]])
{
tot-=1;
f[a[y[i]]]+=f[a[x[i]]];
f[a[x[i]]]=0;
}
}
}
int main()
{
freopen("family.in","r",stdin);
freopen("family.out","w",stdout);
init();
for(i=1;i<=n;i++)
if(used[i]==1) c++;
for(i=1;i<=num;i++)
if(m<f[i]) m=f[i];
tot+=n-c;
if(k==0) printf("%d %d\n",tot,1);
else printf("%d %d\n",tot,m);
return 0;
}


合并果子(fruit)

#include <ctime>
#include <cmath>
#include <cstdio>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define re return
#define s(a)  sizeof(a)
#define maxx(a,b,c) max(max(a,b),c)
#define minx(a,b,c) min(min(a,b),c)
#define up(i,m,n) for(int i=m;i<=n;i++)
#define down(i,m,n) for(int i=n;i>=m;i--)
using namespace std;
const int MAXN=30005;
int a[MAXN],b[MAXN],n;
#define NAME "fruit"
inline int init()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%d",&a[i]);
sort(a+1,a+1+n);
memset(b,67,s(b));
}
inline int solve()
{
int h1=0,t1=n,h2=0,t2=0;
int ans=0;
while (t1-h1+t2-h2>1)
{
int temp=0;
if (h1==t1||h2<t2&&b[h2+1]<a[h1+1])//first
temp+=b[++h2];
else
temp+=a[++h1];
if (h1==t1||h2<t2&&b[h2+1]<a[h1+1])//second
temp+=b[++h2];
else
temp+=a[++h1];
ans+=temp;
b[++t2]=temp;
}
return ans;
}
int main()
{
freopen("fruit.in","r",stdin);
freopen(NAME ".out","w",stdout);
init();
cout<<solve()<<endl;
return 0;
}
法2
#include <ctime>
#include <cmath>
#include <cstdio>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define re return
#define s(a)  sizeof(a)
#define maxx(a,b,c) max(max(a,b),c)
#define minx(a,b,c) min(min(a,b),c)
#define up(i,m,n) for(int i=m;i<=n;i++)
#define down(i,m,n) for(int i=n;i>=m;i--)
using namespace std;
const int MAXN=30005;
int a[MAXN],n;
void com(int x)
{
int i,t,q;
q=x;
for(i=q+1;i<=n;i++)
{
if(a[i]<a[q])
q=i;
}
swap(a[x],a[q]);
}
int main()
{
freopen("fruit.in","r",stdin);
freopen("fruit.out","w",stdout);
int i,sum;
while(scanf("%d",&n))
{
sum=0;
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
com(1);
com(2);
for(i=2;i<=n;i++)
{
a[i]+=a[i-1];
sum+=a[i];
com(i);
com(i+1);
}
printf("%d\n",sum);
}
return 0;
}


下午,以后,共勉!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: