您的位置:首页 > 其它

codeforces tranning11

2014-12-11 13:15 239 查看
A略

Bcf32C Flea

题意:n*m矩阵,跳蚤只能横向竖向跳,每步能跳s,可以跳任意步,问可以达到最多格子的起始点有多少。

分析:行和列没有关联,设行可达最多格的有a格,列b格。若(n-1)整除s,a=(n-1)/s+1,否则,a=((n-1)/s+1)*((n-1)%s+1);列同理。

#include<iostream>
#include<string>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<iomanip>
#include<map>
#include<algorithm>
#include<queue>
#include<set>
#define inf 10000000
#define pi acos(-1.0)
#define eps 1e-8
#define seed 131
using namespace std;
typedef pair<int,int> pii;
typedef unsigned long long ULL;
typedef long long LL;
const int maxn=100005;
LL n,m,s;
LL get(LL p)
{
    if(s>=p||s==1)
        return p;
    if((p-1)%s==0)
        return (p-1)/s+1;
    else
        return ((p-1)/s+1)*((p-1)%s+1);
}
int main()
{
    cin>>n>>m>>s;
    LL a=get(n);
    LL b=get(m);
    cout<<a*b<<endl;
    return 0;
}


C cf31C Schedule

题意:n节课程,每节课程有一个时间段,课程的时间会重复,最多只能删除一节课程,使所有课程都不冲突,输出可以删除的课程编号,否则输出0;

分析:这种题一般是找区间间的关系。此题可以先按左端从小到大排序,从左到右遍历,并不断更新左端点a和右端点b,若有两节课冲突,则可能有4种情况,1.第一节可删除,第二节不可删除 2.第二节可删除,第一节不可删除 3.都可删除 4.都不可删除。(判断方法用a,b 与下一区间比较即可),若为情况4,结果为0,若情况为1,2,3,继续遍历,还有冲突结果为0,没有则输出可删除课程编号。

#include<iostream>
#include<string>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<iomanip>
#include<map>
#include<algorithm>
#include<queue>
#include<set>
#define inf 10000000
#define PI acos(-1.0)
#define eps 1e-8
#define seed 131
using namespace std;
typedef unsigned long long ULL;
typedef long long LL;
typedef pair<int,int> pii;
const int maxn=5005;
int n;
struct Node
{
    int l,r;
    int id;
    bool operator<(const Node& u)const
    {
        return l<u.l;
    }
}node[maxn];
int main()
{
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        scanf("%d%d",&node[i].l,&node[i].r);
        node[i].id=i;
    }
    sort(node,node+n);
    int a=-1,b=-1;
    bool flag=true;
    bool ww=false;
    int u=node[0].id;
    int hand=node[0].l,tail=node[0].r;
    for(int i=1;i<n;i++)
    {
        if(node[i].l<tail)
        {
            if(ww==true)
            {
                flag=false;
                break;
            }
            ww=true;
            if(i==n-1)
            {
                a=u;b=node[i].id;
            }
            else
            {
                int th=hand,tt=tail;
                int er,et,v;
                hand=node[i].l;
                tail=node[i].r;
                if(node[i+1].l>=tail)
                {
                    a=u;
                    er=hand;et=tail;v=node[i].id;
                }
                hand=th;tail=tt;
                if(node[i+1].l>=tail)
                {
                    if(a!=-1)
                        b=node[i].id;
                    else
                        a=node[i].id;
                    er=hand;et=tail;v=u;
                }
                if(a==-1&&b==-1)
                {
                    flag=false;
                    break;
                }
                hand=er;tail=et;u=v;
            }
            continue;
        }
        hand=node[i].l;tail=node[i].r;u=node[i].id;
    }
    if(flag==false)
        printf("0\n");
    else
    {
        int d=0;
        if(a!=-1)
            d++;
        if(b!=-1)
            d++;
        if(d==1)
            printf("%d\n%d\n",d,a+1);
        else if(d==2)
        {
            if(a>b)
                swap(a,b);
            printf("%d\n%d %d\n",d,a+1,b+1);
        }
        else
        {
            printf("%d\n",n);
            for(int i=1;i<=n;i++)
            {
                if(i==n)
                    printf("%d\n",i);
                else
                    printf("%d ",i);
            }
        }
    }
    return 0;
}

D.cf33D Knights 几何

题意:给出n个点的坐标,m个圆的圆心坐标和半径,点不在圆上,有k次询问,每次询问需要答出从一点到另一点需穿过多少个圆(不一定是直线)。

分析:先预处理每个点与每个圆的关系(圆内或圆外),询问两点,遍历这两点与圆的关系,不同则加1.

#include<iostream>
#include<string>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<iomanip>
#include<map>
#include<algorithm>
#include<queue>
#include<set>
#define inf 10000000
#define PI acos(-1.0)
#define eps 1e-8
#define seed 131
using namespace std;
typedef unsigned long long ULL;
typedef long long LL;
typedef pair<int,int> pii;
const int maxn=1005;
int n,m,k;
int point[maxn][2];
int fence[maxn][3];
int guan[maxn][maxn];
int main()
{
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<=n;i++)
        scanf("%d%d",&point[i][0],&point[i][1]);
    for(int i=1;i<=m;i++)
        scanf("%d%d%d",&fence[i][0],&fence[i][1],&fence[i][2]);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            LL a=point[i][0],b=fence[j][1],c=point[i][1],d=fence[j][2];
            LL u=(a-b)*(a-b)+(c-d)*(c-d);
            LL v=LL(fence[j][0])*LL(fence[j][0]);
            if(u>v)
                guan[i][j]=1;//圆外
            else
                guan[i][j]=0;//圆内
        }
    }
    int a,b;
    for(int i=0;i<k;i++)
    {
        scanf("%d%d",&a,&b);
        int ans=0;
        for(int j=1;j<=m;j++)
        {
            if(guan[a][j]!=guan[b][j])
                ans++;
        }
        printf("%d\n",ans);
    }
    return 0;
}
E.cf31D Chocolate 几何

题意:有一块w*h的巧克力,切k刀,每一刀横切或竖切,并每一刀使巧克力块数加1,问k刀之后各块巧克力面积,按升序输出。

分析:为了把线变成点能够标记,把长宽都乘2,另外计算机表示矩阵的行与坐标系表示的y轴相反,变换一下就可以了。

#include<iostream>
#include<string>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<iomanip>
#include<map>
#include<algorithm>
#include<queue>
#include<set>
#define inf 10000000
#define PI acos(-1.0)
#define eps 1e-8
#define seed 131
using namespace std;
typedef unsigned long long ULL;
typedef long long LL;
typedef pair<int,int> pii;
const int maxn=100005;
int d[205][205];
bool vis[205][205];
int num[maxn];
int e=0;
int ans;
int w,h,n;
int dir[4][2]={{0,1},{0,-1},{-1,0},{1,0}};
void dfs(int r,int c);
int main()
{
    scanf("%d%d%d",&w,&h,&n);
    memset(vis,0,sizeof(vis));
    memset(d,-1,sizeof(d));
    for(int i=1;i<2*h;i+=2)
    {
        for(int j=1;j<2*w;j+=2)
            d[i][j]=0;
    }
    int x1,y1,x2,y2;
    for(int i=0;i<n;i++)
    {
        scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
        if(x1==0)
            x1=1;
        else
            x1=2*x1;
        if(x2==0)
            x2=1;
        else
            x2=2*x2;
        y1=(h-y1)*2;y2=(h-y2)*2;
        if(y1==0)y1=1;
        if(y2==0)y2=1;
        if(y1==y2)
        {
            for(int j=x1;j<=x2;j++)
                d[y1][j]=1;
        }
        else
        {
            for(int j=y2;j<=y1;j++)
                d[j][x1]=1;
        }
    }
    for(int i=1;i<2*h;i+=2)
    {
        for(int j=1;j<2*w;j+=2)
        {
            if(vis[i][j]==0)
            {
                ans=0;
                dfs(i,j);
                num[e++]=ans;
            }
        }
    }
    sort(num,num+e);
    for(int i=0;i<e;i++)
    {
        if(i==e-1)
            printf("%d\n",num[i]);
        else
            printf("%d ",num[i]);
    }
    return 0;
}
void dfs(int r,int c)
{
    vis[r][c]=1;
    if(!(r>=1&&r<=2*h)||!(c>=1&&c<=2*w))
        return;
    if(d[r][c]==1)
        return;
    if(d[r][c]==0)
        ans++;
    for(int i=0;i<4;i++)
    {
        if(vis[r+dir[i][0]][c+dir[i][1]]==0)
            dfs(r+dir[i][0],c+dir[i][1]);
    }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: