第四届(2013年十月)福建省大学生程序设计竞赛

G - Easy Game

题目链接

题意:输入一个字符串,判断该字符串长度的奇偶性。相当简单。

/**
   author:liuwen
*/
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
int main()
{
    int T;
    int cas=0;
    scanf("%d",&T);
    while(T--){
        int len=0;
        string str;
        cin>>str;
        len=str.length();
        if(len%2==0){
            printf("Case %d: Even\n",++cas);
        }else{
            printf("Case %d: Odd\n",++cas);
        }
    }
    return 0;
}

H - A-B Game

题目链接

题目大意:输入两个长整型的数a,b。有一种将a变化的操作为:a=a-(a%x),   其中   1<=x<=a-1;

问最少有多少次操作才能使得a<=b。

思路:贪心

因为每次操作a=a-(a%x),1<=x<=a-1,要是操作数最好,那么每次a-(a%x)应该最小。

看如下变形:因为a%x=a-(a/x)*x,   则a-(a%x)=(a/x)*x;要使其最小,x=a/2+1时,(a/x)*x最小。

/**
   author:liuwen
*/
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
using namespace std;
int main()
{
    //freopen("in.txt","r",stdin);
    int T,cas=0;
    scanf("%d",&T);
    while(T--){
        long long a,b,x;
        cin>>a>>b;
        int tot=0;
        while(a>b){
            tot++;
            x=a/2+1;
            a=(a/x)*x;
        }
        cout<<"Case "<<++cas<<": "<<tot<<endl;
    }
    return 0;
}
 
I - Moon Game

题目链接

题目大意:给定n个点的坐标,判断能组成由多少凸四边形。

思路一:枚举三个点a,b,c,这三个点组成三角形ABC(若是直线也被认为是三角形),总剩下的点中取一个d,并判断它是否可以组成凸四边形abcd。

具体方法如下:

/**
   author:liuwen
*/
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const double eps=1e-8;
struct Point{
    int x,y;
    Point(int x=0,int y=0):x(x),y(y){};
}a[50];
typedef Point Vector;
double dcmp(int x)
{
    if(x<0) return -1;
    else  return x<eps?0:1;
}
int cross(Vector a,Vector b)
{
    return a.x*b.y-a.y*b.x;
}
double area(Vector a,Vector b)
{
    return fabs(cross(a,b)*1.0/2);
}
int main()
{
    //freopen("in.txt","r",stdin);
    int T,cas=0;
    scanf("%d",&T);
    while(T--){
        int n;
        scanf("%d",&n);
        for(int i=0;i<n;i++){
            scanf("%d%d",&a[i].x,&a[i].y);
        }
        int tot=0;
        for(int i=0;i<n;i++){
            for(int j=i+1;j<n;j++){
                for(int k=j+1;k<n;k++){
                    for(int z=k+1;z<n;z++){
                            double s1,s2,s3,s4;
                            Vector ab=Vector(a[i].x-a[j].x,a[i].y-a[j].y);
                            Vector ac=Vector(a[i].x-a[k].x,a[i].y-a[k].y);
                            Vector da=Vector(a[z].x-a[i].x,a[z].y-a[i].y);
                            Vector db=Vector(a[z].x-a[j].x,a[z].y-a[j].y);
                            Vector dc=Vector(a[z].x-a[k].x,a[z].y-a[k].y);
                            s1=area(ab,ac);
                            s2=area(da,db);
                            s3=area(da,dc);
                            s4=area(db,dc);
                            if(dcmp(s1+s2+s3-s4)==0||dcmp(s1+s2+s4-s3)==0||dcmp(s2+s3+s4-s1)==0||dcmp(s1+s3+s4-s2)==0) continue;
                            tot++;

                    }
                }
            }
        }
        printf("Case %d: %d\n",++cas,tot);
    }
    return 0;
}
思路二:当且仅当四边形为凸四边形时,对角线能相交 -> 若四边形存在线段相交就是凸四边形(看九野的报告才知道的)

对角线相交的思路


K - Fire Game

题目链接

题目大意:给定一个图,‘.’表示空地,'#'表示草地。选择2块草地为放火点,火势每秒向上下左右蔓延。

开始时间为0,问所有草地被燃烧的最少时间。如果不能,则输出-1。


思路;枚举两个块草地u,v。然后以这两个点为原点进行bfs。dist[i][j]表示草地i到草地j的最短距离。dist[][]初始化为Inf。

那么每次枚举的两块草地u,v后,就对得到一张dist[][]的二维表,每次取所有草地i,j的dist[i][j]的最大值_max,如果存在dist[i][j],则表示该种枚举方式(u,v为源点)不能满足要求

最后取所有枚举(u,v)中_max的最小值为ans。

注意:如果草地的数量<=2,则输出0;

否则,若ans=inf,则为-1.

/**
   author:liuwen
*/
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <climits>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
const int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
const int inf=INT_MAX;
struct Node{
    int x,y;
    Node(int x=0,int y=0):x(x),y(y){};
};
int vis[15][15],G[15][15],dist[15][15];
vector<Node>v;
int n,m;
bool isok(int x ,int y)
{
    if(x>=0&&x<n&&y>=0&&y<m)    return true;
    else    return false;
}
void initial_Map()
{
    scanf("%d%d",&n,&m);
    char str[15];
    memset(vis,0,sizeof(vis));
    memset(G,0,sizeof(G));
    v.clear();
    for(int i=0;i<n;i++){
        cin>>str;
        for(int j=0;j<m;j++){
            if(str[j]=='#') G[i][j]=1,v.push_back(Node(i,j));
        }
    }
}
int bfs(Node a,Node b)
{
    for(int i=0;i<=n;i++){
        fill(dist[i],dist[i]+m,inf);
    }
    queue<Node>que;
    que.push(a);que.push(b);
    dist[a.x][a.y]=0,dist[b.x][b.y]=0;
    while(!que.empty()){
        Node tmp=que.front();
        que.pop();
        for(int k=0;k<4;k++){
            int nowX=tmp.x+dir[k][0];
            int nowY=tmp.y+dir[k][1];
            if(isok(nowX,nowY)&&G[nowX][nowY]){
                if(dist[nowX][nowY]>dist[tmp.x][tmp.y]+1){
                    dist[nowX][nowY]=dist[tmp.x][tmp.y]+1;
                    que.push(Node(nowX,nowY));
                }
            }
        }
    }
    int _min=-1000;
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++) if(G[i][j])
            _min=max(_min,dist[i][j]);
    }
    return _min;
}
int main()
{
    //freopen("in.txt","r",stdin);
    int T,cas=0;
    scanf("%d",&T);
    while(T--){
        initial_Map();
        int s=v.size();
        if(s<=2){
            printf("Case %d: 0\n",++cas);
            continue;
        }
        int ans=inf;
        for(int i=0;i<s;i++){
            for(int j=i+1;j<s;j++){
                ans=min(ans,bfs(v[i],v[j]));
            }
        }
        if(ans==inf)    printf("Case %d: -1\n",++cas);
        else    printf("Case %d: %d\n",++cas,ans);
    }
    return 0;
}

L - OOXX Game

题目链接

题意和题目思路很简单:如‘O’的数量为奇数为 “Maze”,否则为"Fat brother";

/**
   author:liuwen
*/
#include <iostream>
#include <cstdio>
#include <map>
#include <algorithm>
using namespace std;
int main()
{
   // freopen("in.txt","r",stdin);
    int T,cas=0;
    scanf("%d",&T);
    while(T--){
        int zero=0;
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                char ch;
                cin>>ch;
                if(ch=='O') zero++;
            }
        }
        if(zero%2)  printf("Case %d: Maze\n",++cas);
        else    printf("Case %d: Fat brother\n",++cas);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值