概述
我能说我1016WA了几天都不得最后还是拿别人代码交的么。。。
真心找不到那个神数据。。。
自己把整个程序的流程都画出来了,仔细推敲是木有问题的啊。。。
题目地址:点击打开链接
先从1013开始介绍。
题目大意:给你n个城市,m条路,k个询问,每次询问,是如果没有城市q1,,,qk其他城市链接在一起至少需要多少条路。简单的并查集问题。对节点qi不管,其他的点用并查集,我们所要求的就是有多少个分量,ans个分量则需要ans-1条路即可,详见代码:
AC代码:
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
const int maxn=1005;
struct node
{
int x;
int y;
}nod[maxn*maxn];
int fa[maxn];
void init()
{
for(int i=1;i<=1000;i++)
fa[i]=i;
}
int find1(int p)
{
if(fa[p]!=p) fa[p]=find1(fa[p]);
return fa[p];
}
void merge1(int p,int q)
{
p=find1(p);
q=find1(q);
if(p!=q)
fa[p]=q;
}
int main()
{
int n,m,k;
int i;
while(cin>>n>>m>>k)
{
for(i=0;i<m;i++)
scanf("%d%d",&nod[i].x,&nod[i].y);
int cur;
while(k--)
{
scanf("%d",&cur);
int res=0;
init();
for(i=0;i<m;i++)
{
int p,q;
p=nod[i].x,q=nod[i].y;
if(p==cur||q==cur) continue;
merge1(p,q);
}
for(i=1;i<=n;i++)
{
if(i==cur) continue;
if(fa[i]==i) res++;
}
printf("%dn",res-1);
}
}
return 0;
}
/*
3 2 3
1 2
1 3
1 2 3
*/
1014:
题目大意:题目有点麻烦,意思是在取钱之类的背景下。。有n个窗口,每个窗口黄线里面最多容下的人数m,k个客户,q个查询。然后依次给出你k个客户的在柜台的处理时间,然后q个查询,每次查询编号为qi的客户处理完之后的时间。时间是08:00开始,17:00结束。
注意,这里有个bug,17:00结束是如果你在17:00之前还在柜台前面,就会被处理。
解题思路:最开始我们先把队伍一个一个排好,因为题目说的意思是每次都会排在最少人数的队列中,如果队列人数有一样的,选编号小的。那么我们最开始处理的时候就先把n*m容量之类的排好,一个一个按着队列排,然后出一个进一个,依次模拟,详见代码:
AC代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<queue>
#include<cstring>
using namespace std;
int n,m,k,peo,ccnt;
struct node
{
int t;
int index;
} nod[1005];
queue <node> mq[25];
int res[1005];
int mp[25];
void debug()
{
for(int i=1; i<=2; i++)
{
node x=mq[i].front();
cout<<x.t<<" ";
mq[i].pop();
x=mq[i].front();
cout<<x.t<<endl;
}
}
void init() //初始化,先预先站队
{
int i,j;
for(int i=1;i<=1000;i++)
res[i]=10000;
for(i=1; i<=20; i++)
{
while(!mq[i].empty())
mq[i].pop();
}
int cnt=0;
for(i=1; i<=k; i+=n)
{
for(j=0; j<n; j++)
{
if(cnt==n*m)
{
//debug();
peo=cnt+1;
return;
}
mq[j+1].push(nod[i+j]);
cnt++;
}
}
peo=cnt+1; //peo代表下一个排队人的编号
return;
}
void resolve() //时间到了16:59,只有reserved的人才可以完成交易
{
int i;
for(i=1; i<=n; i++)
{
if(!mq[i].empty())
{
node x=mq[i].front();
res[x.index]=ccnt+mp[i];
}
}
return;
}
void solve()
{
ccnt=1;
for(int i=1; i<=n; i++)
{
if(!mq[i].empty())
{
node x=mq[i].front();
mp[i]=x.t;
}
}
while(1)
{
if(ccnt==540)
{
ccnt--;
resolve(); //时间已到,只处理在队首的
break;
}
for(int i=1; i<=n; i++)
{
if(!mq[i].empty())
{
mp[i]--;
if(mp[i]==0) //如果某个队伍有人完成交易,立马填充人进来
{
node x=mq[i].front();
mq[i].pop();
res[x.index]=ccnt;
if(peo<=k)
mq[i].push(nod[peo++]);
if(!mq[i].empty())
{
node x=mq[i].front();
mp[i]=x.t;
}
}
}
}
ccnt++;
}
}
int main()
{
int q,i;
while(cin>>n>>m>>k>>q)
{
for(i=1; i<=k; i++)
{
cin>>nod[i].t;
nod[i].index=i;
}
init();
solve();
//cout<<res[6]<<endl;
int x;
while(q--)
{
cin>>x;
if(res[x]==10000)
puts("Sorry");
else printf("%02d:%02dn",(res[x]+480)/60,(res[x]+480)%60);
}
}
return 0;
}
/*
2 2 7 5
1 2 6 4 3 534 2
3 4 5 6 7
*/
1015:
题目大意:给你两个数n,b,我们记另一个数是m,将n转换为b进制然后再倒转再转换成10进制变成m,如果n和m都是素数,那么yes,否则no。
直接模拟就好。
AC代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<queue>
#include<cstring>
using namespace std;
const int maxn=1005;
int a[maxn];
int base;
int isprime(int x)
{
if(x==1||x==0) return 0;
for(int i=2;i<=sqrt(x+0.5);i++)
{
if(x%i==0) return 0;
}
return 1;
}
int verse(int x)
{
int p=x;
int cnt=0;
while(p)
{
a[cnt++]=p%base;
p/=base;
}
int ans=0;
for(int i=0;i<cnt;i++)
{
ans=ans*base+a[i];
}
return ans;
}
int main()
{
int x;
while(cin>>x&&x>=0)
{
cin>>base;
int y=verse(x);
//cout<<y<<endl;
if(isprime(x)&&isprime(y)) puts("Yes");
else puts("No");
}
return 0;
}
/*
73 10
23 2
23 10
-2
*/
1016:
因为这个1016,真的被伤了。。。。
题目大意:主题是算话费的,先给你24小时每小时内每分钟的资费,分别是00:00-01:00,01:00-02:00的每分钟话费,单位是美分,然后给你n个电话记录,每条记录会有用户名,月:天:时:分,然后是一个状态,online表示打电话,offline表示挂电话。所以我们要排序匹配。而题目中说了保证每个人的记录是一个月份内的。
并且如果某人的记录没一个能匹配的话就不打印他的账单。
估计是自己的代码写挫了。。。
(15分/25分)代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<queue>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const double eps=1e-10;
int rate[26]; //每小时里1分钟的价钱
int n; //多少个记录
struct node
{
char name[25];
char time[25];
int month;
int day;
int hour;
int minu;
int fla;
} bill[1005];
struct nod
{
char ans1[25];
char ans2[25];
int curt;
double mon;
} ans[1005];
int cmp(node p1,node p2)
{
if(strcmp(p1.name,p2.name)<0)
return 1;
else if(strcmp(p1.name,p2.name)==0&&strcmp(p1.time,p2.time)<0)
return 1;
return 0;
}
double cal1(int day,int hour,int minu) //计算money
{
double ans=0;
ans+=(double)day*rate[25]*60;
for(int i=1; i<hour+1; i++)
ans+=rate[i]*60;
ans+=(double)rate[hour+1]*minu;
return ans/100.0;
}
int cal2(int day,int hour,int minu) //计算时间
{
return day*24*60+hour*60+minu;
}
void solve()
{
char ansname[25];
int cnt;
int month;
cnt=0;
int p=0;
//cout<<bill[0].time<<" "<<bill[0].month<<endl;
//for(int i=0; i<n; i++)
//cout<<i<<" "<<bill[i].name<<" "<<bill[i].time<<" "<<bill[i].fla<<endl;
while(p<n) //最开始先找一个online的位置p
{
if(bill[p].fla==1)
{
strcpy(ansname,bill[p].name);
month=bill[p].month;
p++;
break;
}
else p++;
}
//cout<<ansname<<" "<<month<<endl;
//cout<<p<<endl;
double total=0; //记录一个月的花费
int flag=1; //flag=1代表有online,
//puts("fuck1");
while(p<n)
{
//cout<<p<<"****"<<endl;
if(strcmp(ansname,bill[p].name)!=0)
{
//cout<<"????"<<cnt<<endl;
if(cnt>0)
{
printf("%s %02dn",ansname,month);
for(int i=0; i<cnt; i++)
{
printf("%s %s %d $%.2fn",ans[i].ans1,ans[i].ans2,ans[i].curt,ans[i].mon);
}
printf("Total amount: $%.2fn",total);
total=0;
cnt=0;
}
flag=0;
while(p<n) //刚处理完一个人的,寻找下一个online的
{
if(bill[p].fla==1)
{
strcpy(ansname,bill[p].name);
month=bill[p].month;
p++;
flag=1;
break;
}
else p++;
}
}
else //说明当前是一个月一个人的。
{
if(bill[p].fla==0&&flag) //开始计算
{
ans[cnt].curt=cal2(bill[p].day,bill[p].hour,bill[p].minu)-
cal2(bill[p-1].day,bill[p-1].hour,bill[p-1].minu);
ans[cnt].mon=cal1(bill[p].day,bill[p].hour,bill[p].minu)-
cal1(bill[p-1].day,bill[p-1].hour,bill[p-1].minu);
total+=ans[cnt].mon;
char tmp1[25],tmp2[25];
for(int i=0; i<8; i++)
{
tmp1[i]=bill[p-1].time[i+3];
tmp2[i]=bill[p].time[i+3];
}
tmp1[8]=tmp2[8]-'