P144 UVa12657 移动盒子 Boxes in a Line
#include<cstdio>
typedef long long LL;
LL n,m;
LL l[100010],r[100010],p;//双向链表
LL case1;//记录这是第几种情况
int main()
{
LL t,ans,i,a,x,y,k;
while(scanf("%lld%lld",&n,&m)==2)
{
p=0;//记录现在顺序是正的还是反的
for(i=1;i<=n;i++)
{
l[i]=i-1;r[i]=i+1;
}
for(i=1;i<=m;i++)
{
scanf("%lld",&a);
if(a==4)
p=!p;
else
{
if(a!=3&&p) a=3-a;//忘了加导致错,因为如果p不为0表示顺序是颠倒的
//而我们只是记录了p,并没有实际颠倒过来,因此p不为0时操作左侧实际要右侧,操作右侧实际要操作左侧
scanf("%lld%lld",&x,&y);
if(a==1)
{
if(x==l[y]) continue;//忘了加,其实可以不加
r[l[x]]=r[x];
l[r[x]]=l[x];
r[l[y]]=x;
l[x]=l[y];
r[x]=y;
l[y]=x;
}
if(a==2)
{
if(x==r[y]) continue;//忘了加,其实可以不加
r[l[x]]=r[x];
l[r[x]]=l[x];
l[r[y]]=x;
r[x]=r[y];
l[x]=y;
r[y]=x;
}
if(a==3)
{
if(r[y]==x)
{
t=y;
y=x;
x=t;
}
if(r[x]==y)
{
r[l[x]]=y;
l[r[y]]=x;
l[y]=l[x];
r[x]=r[y];
l[x]=y;
r[y]=x;
}
//曾经忽略了x、y相邻时交换的特殊情况,就是上面的情况,导致错误
else
{
r[l[x]]=y;
r[l[y]]=x;
l[r[x]]=y;
l[r[y]]=x;
t=r[x];
r[x]=r[y];
r[y]=t;
t=l[x];
l[x]=l[y];
l[y]=t;
}
}
}
}
t=0;
ans=0;
if(p==0)
{
for(i=1;i<=n;i++)
if(l[i]==0)
{
k=i;
while(k!=n+1)
{
t=not t;
if(t)
ans+=k;
k=r[k];
}
break;
}
}
else
{
for(i=1;i<=n;i++)
if(r[i]==n+1)
{
k=i;
while(k!=0)
{
t=not t;
if(t)
ans+=k;
k=l[k];
}
}
}
printf("Case %lld: %lld\n",++case1,ans);
}
return 0;
}
P138 UVa212 医院设备利用 Use of Hospital Facilities
#include<iostream>
#include<cstring>
//出过错:病人要去的恢复室,是根据做完手术那一刻编号最小的空的恢复室决定的
//而不是到之后编号最小的空的恢复室
//出过错:那个the patient with the lower number指的是在门牌号小的手术室做手术的患者。那个number竟然指的门牌号!http://www.cnblogs.com/xienaoban/p/6798078.html
#include<string>
#include<queue>
using namespace std;
struct Patient
{
string name;
int room,b1,e1,bed,b2,e2;//分别记录病人的手术室,手术开始时间,手术结束时间,恢复室,恢复开始时间,恢复结束时间
int t1,t2;//分别记录病人的手术和恢复时间
}pt[110];
int rm[11],bd[31];//记录room和bed的使用时间
struct Query
{
int room,end,ptn;
Query(){}
Query(int b,int c,int d)
{
room=b;end=c;ptn=d;
}
friend bool operator<(const Query&a,const Query& b)
{
return (a.end>b.end)||(a.end==b.end&&a.room>b.room)||(a.end==b.end&&a.room==b.room&&a.ptn>b.ptn);
}//这个排序对于病人做手术、从手术出来、恢复的排序都有效
};
int q_num=0;
priority_queue<Query> q1;
priority_queue<Query> q2;//记录病人从手术室出来的顺序(就是pop的顺序)、结束时间(end)、做手术的房间(room)
bool boo[31];
int n,m,T,t1,t2,t3,k,maxt;
int main()
{
int i;
while(scanf("%d%d%d%d%d%d%d",&n,&m,&T,&t1,&t2,&t3,&k)==7)//出过错:当成单组数据了
{
memset(boo,0,sizeof(boo));
memset(rm,0,sizeof(rm));
memset(bd,0,sizeof(bd));
maxt=-1;
T=60*T;
for(i=1;i<=k;i++)
{
cin>>pt[i].name;
scanf("%d%d",&pt[i].t1,&pt[i].t2);
}
Query qt,qt2;
for(i=1;i<=min(n,k);i++)
{
q1.push(Query(i,pt[i].t1+T,i));
pt[i].b1=T;
pt[i].room=i;
}
for(i=min(n,k)+1;i<=k;i++)
{
qt=q1.top();
q1.pop();
rm[qt.room]+=pt[qt.ptn].t1;
pt[qt.ptn].e1=qt.end;
q1.push(Query(qt.room,qt.end+t2+pt[i].t1,i));
pt[i].b1=qt.end+t2;
pt[i].room=qt.room;
q2.push(Query(qt.room,qt.end,qt.ptn));
}
while(!q1.empty())
{
qt=q1.top();
q1.pop();
rm[qt.room]+=pt[qt.ptn].t1;
pt[qt.ptn].e1=qt.end;
q2.push(Query(qt.room,qt.end,qt.ptn));
}
// while(!q2.empty())
// {
// qt=q2.top();
// q2.pop();
// printf("%d %d %d\n",qt.end,qt.ptn,pt[qt.ptn].t2+qt.end);
// }
// for(i=1;i<=n;i++)
// printf("%d %d\n",i,rm[i]);
// for(i=1;i<=k;i++)
// printf("%d %d %d\n",pt[i].room,pt[i].b1,pt[i].e1);
while(!q2.empty())
{
qt=q2.top();
q2.pop();
while(!q1.empty())
{
qt2=q1.top();
if(qt2.end+t3<=qt.end)//出过错:没加等号
{
q1.pop();
pt[qt2.ptn].e2=qt2.end;
boo[qt2.room]=false;
bd[qt2.room]+=pt[qt2.ptn].t2;
maxt=max(maxt,qt2.end);
}
else
break;
}
for(i=1;i<=m;i++)
if(boo[i]==false)
{
boo[i]=true;
q1.push(Query(i,qt.end+pt[qt.ptn].t2+t1,qt.ptn));
pt[qt.ptn].b2=qt.end+t1;
pt[qt.ptn].bed=i;
break;
}
}
while(!q1.empty())
{
qt2=q1.top();
q1.pop();
maxt=max(maxt,qt2.end);
bd[qt2.room]+=pt[qt2.ptn].t2;
pt[qt2.ptn].e2=qt2.end;
}
printf(" Patient Operating Room Recovery Room\n");
printf(" # Name Room# Begin End Bed# Begin End\n");
printf(" ------------------------------------------------------\n");
for(i=1;i<=k;i++)
printf("%2d %-10s%2d %2d:%02d %2d:%02d %2d %2d:%02d %2d:%02d\n",i,pt[i].name.c_str(),pt[i].room,pt[i].b1/60,pt[i].b1%60,pt[i].e1/60,pt[i].e1%60,pt[i].bed,pt[i].b2/60,pt[i].b2%60,pt[i].e2/60,pt[i].e2%60);
printf("\nFacility Utilization\nType # Minutes % Used\n");
printf("-------------------------\n");
maxt-=T;
for(i=1;i<=n;i++)
printf("Room %2d %4d %5.2f\n",i,rm[i],(double)rm[i]*100/maxt);
for(i=1;i<=m;i++)
printf("Bed %2d %4d %5.2f\n",i,bd[i],(double)bd[i]*100/maxt);
printf("\n");//注意:不要少空行
}
return 0;
}
P148 UVa 679 小球下落 Dropping Balls
记在滚某个球时,滚到节点i的次数为a[i]
显然,如果a[i]为奇数,那么a[i*2]为(a[i]+1)/2,a[i*2+1]为(a[i]-1)/2(如果直接整除的话也可以表示为a[i]/2)
(原因是a[i]为奇数,那么前面a[i]-1次必定是左右各走(a[i]-1)/2次,这一次必定是向左走)
如果a[i]为偶数,那么a[i*2]=a[i*2+1]=a[i]/2
而且如果a[i]为奇数,那么下一步会往a[i*2]走
如果a[i]为偶数,那么下一步会往a[i*2+1]走
显然a[1]就是题目中的I,那么现在可以求出叶子节点了
这再次说明了写程序不如多想想
P154
对比:
#include<cstdio>
int b[100000001];
int *a;
int main()
{
int i;
a=(int*)&b;
*a=29;
for(int i=1;i<=100000000;i++)
*(a+i)=(*(a+i-1)+*(a+i-2))*2%10000000;
printf("%d",*(a+10000000));
}
#include<cstdio>
int b[100000001];
int *a;
int main()
{
int i;
a=(int*)&b;
*a=29;
for(i=1;i<=100000000;i++)
b[i]=(b[i-1]+b[i-2])*2%10000000;
printf("%d",b[10000000]);
}
内存池
P160 UVa 297 四分树 Quadtrees
输出测试数据(?):
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
int a[33][33];
void print(int l1,int l2,int w)
{
bool b1=false,b2=false;
int i,j;
if(w==1)
{
if(a[l1][l2]==0)
printf("e");
else
printf("f");
return;
}
for(i=0;i<w;i++)
for(j=0;j<w;j++)
{
if(a[l1+i][l2+j]==0)
b1=true;
if(a[l1+i][l2+j]==1)
b2=true;
if(b1&&b2)
goto haha;
}
haha:
if(b1&&(!b2))
printf("e");
else if((!b1)&&b2)
printf("f");
else
{
printf("p");
print(l1+w/2,l2,w/2);
print(l1,l2,w/2);
print(l1,l2+w/2,w/2);
print(l1+w/2,l2+w/2,w/2);
}
}
int main()
{
int i,j;
srand(time(0));
printf("1\n");
memset(a,0,sizeof(a));
for(i=1;i<=32;i++)
for(j=1;j<=32;j++)
a[i][j]=rand()%2;
print(1,1,32);
printf("\n");
for(i=1;i<=32;i++)
for(j=1;j<=32;j++)
a[i][j]=rand()%2;
print(1,1,32);
}
程序:
#include<cstdio>
#include<cstring>
int ans;//答案
int buf[35][35];//记录draw出来的正方形
char s[2000];//曾经未注意,开太小了,实际上最大远远大于32*32,因为一个2*2的格子,最多占5个字符而不是4个,更多的类似
int p,n;//当前字符序号
//把s绘制到以(r,c)为左上角,边长为w的buf中
void draw(const char* s,int r,int c,int w)
{
char ch=s[p++];
int i,j;
if(ch=='p')
{
draw(s,r+w/2,c,w/2);
draw(s,r,c,w/2);
draw(s,r,c+w/2,w/2);
draw(s,r+w/2,c+w/2,w/2);
//举例:最开始0-31,0-31
/*分开:
1:16-31,0-15
2:0-15,0-15
3:0-15,16-31
4:16-31,16-31
*/
}
else if(ch=='f')
for(i=0;i<w;i++)
for(j=0;j<w;j++)
if(buf[r+i][c+j]==0)
{
ans++;
buf[r+i][c+j]=1;
}
}
int main()
{
int i;
scanf("%d",&n);
for(i=1;i<=n;i++)
{
ans=0;
//memset(s,0,sizeof(s));
memset(buf,0,sizeof(buf));
scanf("%s",s);
p=0;
draw(s,0,0,32);
scanf("%s",s);
p=0;
draw(s,0,0,32);
printf("There are %d black pixels.\n",ans);
}
return 0;
}