题目链接:http://codeforces.com/problemset/problem/237/A
A题:题意:判断在同一分钟内最多可能有多少个顾客。
1WA,没考虑0的情况,1WA扣的分太多了,交的时候还是先看看范围考虑的怎么样,毕竟别人出的慢也可能比你出的快的分高。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int v[100000];
int main()
{
int n,a,b;
cin>>n;
memset(v,0,sizeof(v));
for(int i=1;i<=n;i++)
{
cin>>a>>b;
v[a*60+b]++;
}
int max=0;
for(int i=0;i<=10000;i++)
{
if(max<v[i])
max=v[i];
}
cout<<max<<endl;
return 0;
}
B题:题意:首先得把二维的矩阵变成一维的数组,求使数组有序的交换次数(只要小于点的个数就行)。
完全被坑了,不知道交换数小于s(点的个数)就行。这也是一种思路题吧,Special Charge。解不是唯一的,开始看给的数据,一直在想答案是怎么来的,其实不一定要按照给的数据来,只要满足题目要求就行了,这也给了我们一个提示,要好好看题目呀~~~
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 55
struct node
{
int x,y;
}p[3005];
struct node2
{
int x1,y1,x2,y2;
}p2[3005];
int a[55];
int b[3005];
using namespace std;
int num=0;
int main()
{
int n,m;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
//int num=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=a[i];j++)
{
num++;
cin>>b[num];
p[num].x=i,p[num].y=j;
}
}
int id=0;
for(int i=1;i<=num;i++)
{
int min=b[i];
m=i;
for(int j=i+1;j<=num;j++)
{
if(min>b[j])
{
min=b[j];
m=j;
}
}
if(m==i)continue;
p2[id].x1=p[i].x,p2[id].y1=p[i].y;
p2[id].x2=p[m].x,p2[id].y2=p[m].y;
id++;
int tmp=b[m];
b[m]=b[i];
b[i]=tmp;
}
cout<<id<<endl;
for(int i=0;i<id;i++)
{
printf("%d %d %d %d\n",p2[i].x1,p2[i].y1,p2[i].x2,p2[i].y2);
}
return 0;
}
C题:找最小的数,使得满足题目要求。
二分的题,一开始还以为是数论题,直接没怎么看。二分应用的很广,特别是查找最优解,这题再一次给了我们提示,最优解用二分。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 1000005
using namespace std;
int a,b,k;
int prim[maxn];
int isPrim[maxn];
void init()
{
isPrim[0]=isPrim[1]=0;
prim[0]=prim[1]=0;
for(int i=2;i<maxn;i++)
{
prim[i]=prim[i-1];
if(isPrim[i]==0)
{
prim[i]++;
for(int j=i;j<maxn;j+=i)
{
isPrim[j]=1;
}
}
}
}
bool f(int l)
{
bool flag=true;
for(int x=a;x<=b-l+1;x++)
{
if(prim[x+l-1]-prim[x-1]<k)
{
flag=false;
break;
}
}
return flag;
}
int main()
{
cin>>a>>b>>k;
init();
int left=1,right=b-a+1,mid;
while(left<=right)
{
mid=(left+right)>>1;
if(f(mid))
{
right=mid-1;
}
else
{
left=mid+1;
}
}
if(left<=b-a+1)
cout<<left<<endl;
else
cout<<-1<<endl;
return 0;
}
D题:题意:用一棵普通的树构造划分为T个集合(点可以重复分给多个集合),把这些集合看成新的树的节点,并且满足要求:
1.原树的每条边必须在这些集合中。
2.若两个集合有一个公共的点,则这两个集合必须有边。
求新树所有节点集合含有原树的节点个数最小的树,可能有多种情况,输出任意一种。
这题关键还是读懂题吧,细心,有耐心的话应该没问题,这也提示我们以后得多注意读题,不要因为题目太长就没耐心。这题只要把每条边所含的两个点看成一个集合xi,然后把含有公共点的集合xi,xj连一条边就行了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#define maxn 100005
using namespace std;
struct e
{
int x,y;
}edg[maxn];
vector<int> g[maxn];
int main()
{
int n;
cin>>n;
for(int i=1;i<n;i++)
{
cin>>edg[i].x>>edg[i].y;
g[edg[i].x].push_back(i);
g[edg[i].y].push_back(i);
}
cout<<n-1<<endl;
for(int i=1;i<n;i++)
{
cout<<2<<' ';
cout<<edg[i].x<<' '<<edg[i].y<<endl;
}
for(int i=1;i<=n;i++)
{
if(g[i].size()>=2)
{
int root=g[i][0];
for(int j=1;j<g[i].size();j++)
{
cout<<root<<' '<<g[i][j]<<endl;
}
}
}
return 0;
}
E题:最小费用最大流,图论都忘了。暂时先不搞图论。