现在的位置: 首页 > 综合 > 正文

CF237

2019年02月09日 ⁄ 综合 ⁄ 共 2662字 ⁄ 字号 评论关闭

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

【上篇】
【下篇】

抱歉!评论已关闭.