题目链接: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题:最小费用最大流,图论都忘了。暂时先不搞图论。