湖南省第十一届大学生计算机程序设计竞赛 部分题解 待续

【PS】由于这些题应该找不到题解,所以只能把我能做出来的先放在这里,其他的等出题解了补上。

B - 大还是小?】http://acm.hust.edu.cn/vjudge/contest/130626#problem/B

【题意】中文题目。

【解题方法】水题。

【AC 代码】

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const double eps=1e-100;
double a,b;
int main()
{
    int cas=1;
    while(scanf("%lf%lf",&a,&b)!=EOF)
    {
        if((a-b)>=0.00000000000000000&&(a-b)<eps) printf("Case %d: Same\n",cas++);
        else if((a-b)<0.0000000000000000) printf("Case %d: Smaller\n",cas++);
        else printf("Case %d: Bigger\n",cas++);
    }
    return 0;
}

C - 多边形的公共部分】 http://acm.hust.edu.cn/vjudge/contest/130626#problem/C

【题意】中文题目,面积并水题,模板。

【解题方法】模板题。

【AC 代码】

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<algorithm>
const int maxn = 555;
const int maxisn = 10;
const double eps = 1e-8;
const double pi = acos(-1.0);
int dcmp(double x)
{
    if(x > eps) return 1;
    return x < -eps ? -1 : 0;
}
inline double min(double a, double b)
{return a < b ? a : b;}
inline double max(double a, double b)
{return a > b ? a : b;}
inline double Sqr(double x)
{return x * x;}
struct Point
{
    double x, y;
    Point(){x = y = 0;}
    Point(double a, double b)
    {x = a, y = b;}
    inline Point operator-(const Point &b)const
    {return Point(x - b.x, y - b.y);}
    inline Point operator+(const Point &b)const
    {return Point(x + b.x, y + b.y);}
    inline double dot(const Point &b)const
    {return x * b.x + y * b.y;}
    inline double cross(const Point &b, const Point &c)const
    {return (b.x - x) * (c.y - y) - (c.x - x) * (b.y - y);}
};
Point LineCross(const Point &a, const Point &b, const Point &c, const Point &d)
{
    double u = a.cross(b, c), v = b.cross(a, d);
    return Point((c.x * v + d.x * u) / (u + v), (c.y * v + d.y * u) / (u + v));
}
double PolygonArea(Point p[], int n)
{
    if(n < 3) return 0.0;
    double s = p[0].y * (p[n - 1].x - p[1].x);
    p[n] = p[0];
    for(int i = 1; i < n; ++ i)
        s += p[i].y * (p[i - 1].x - p[i + 1].x);
    return fabs(s * 0.5);
}
double CPIA(Point a[], Point b[], int na, int nb)//ConvexPolygonIntersectArea
{
    Point p[maxisn], tmp[maxisn];
    int i, j, tn, sflag, eflag;
    a[na] = a[0], b[nb] = b[0];
    memcpy(p, b, sizeof(Point) * (nb + 1));
    for(i = 0; i < na && nb > 2; ++ i)
    {
        sflag = dcmp(a[i].cross(a[i + 1], p[0]));
        for(j = tn = 0; j < nb; ++ j, sflag = eflag)
        {
            if(sflag >= 0) tmp[tn ++] = p[j];
            eflag = dcmp(a[i].cross(a[i + 1], p[j + 1]));
            if((sflag ^ eflag) == -2)
                tmp[tn ++] = LineCross(a[i], a[i + 1], p[j], p[j + 1]);
        }
        memcpy(p, tmp, sizeof(Point) * tn);
        nb = tn, p[nb] = p[0];
    }
    if(nb < 3) return 0.0;
    return PolygonArea(p, nb);
}
double SPIA(Point a[], Point b[], int na, int nb)//SimplePolygonIntersectArea
{
    int i, j;
    Point t1[4], t2[4];
    double res = 0, if_clock_t1, if_clock_t2;
    a[na] = t1[0] = a[0], b[nb] = t2[0] = b[0];
    for(i = 2; i < na; ++ i)
    {
        t1[1] = a[i - 1], t1[2] = a[i];
        if_clock_t1 = dcmp(t1[0].cross(t1[1], t1[2]));
        if(if_clock_t1 < 0) std::swap(t1[1], t1[2]);
        for(j = 2; j < nb; ++ j)
        {
            t2[1] = b[j - 1], t2[2] = b[j];
            if_clock_t2 = dcmp(t2[0].cross(t2[1], t2[2]));
            if(if_clock_t2 < 0) std::swap(t2[1], t2[2]);
            res += CPIA(t1, t2, 3, 3) * if_clock_t1 * if_clock_t2;
        }
    }
    return PolygonArea(a, na) + PolygonArea(b, nb) - res;
}
Point p1[maxn], p2[maxn];
int n, m;
int main()
{
    int cas=1;
    while(scanf("%d",&n)!=EOF)
    {
        for(int i=0; i<n; i++) scanf("%lf%lf",&p1[i].x,&p1[i].y);
        scanf("%d",&m);
        for(int i=0; i<m; i++) scanf("%lf%lf",&p2[i].x,&p2[i].y);
        double area1=PolygonArea(p1,n);
        double area2=PolygonArea(p2,m);
        double area3=SPIA(p1,p2,n,m);
        if((area1+area2-area3)>eps) printf("Case %d: Yes\n",cas++);
        else printf("Case %d: No\n",cas++);
    }
    return 0;
}

D - 错误的算法】 http://acm.hust.edu.cn/vjudge/contest/130626#problem/D

【题意】中文题目

【解题方法】模拟就行啦。

【AC 代码】

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 505;
const int maxm = 505;
int a[maxn][maxm];
int row[maxn],col[maxn];
int n,m;
int main()
{
    int cas=1;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        memset(row,0,sizeof(row));
        memset(col,0,sizeof(col));
        for(int i=1; i<=n; i++)
            for(int j=1; j<=m; j++) scanf("%d",&a[i][j]);
        //
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=m; j++)
            {
                row[i]+=a[i][j];
            }
        }
        for(int i=1; i<=m; i++)
        {
            for(int j=1; j<=n; j++)
            {
                col[i]+=a[j][i];
            }
        }
        //
        int ansx=-1,ansy=-1,ansxid=-1,ansyid=-1;
        for(int i=1; i<=n; i++)
        {
            ansx=max(ansx,row[i]);
        }
        for(int i=1; i<=m; i++)
        {
            ansy=max(ansy,col[i]);
        }
        for(int i=1; i<=n; i++)
        {
            if(ansx==row[i]){
                ansxid=i;
                break;
            }
        }
        for(int i=1; i<=m; i++)
        {
            if(ansy==col[i]){
                ansyid=i;
                break;
            }
        }
        //
        bool flag=true;
        int ans=ansx+ansy-a[ansxid][ansyid];
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=m; j++)
            {
                if(row[i]+col[j]-a[i][j]>ans)
                {
                    flag=false;
                    break;
                }
            }
            if(!flag) break;
        }
        if(flag) printf("Case %d: Weak\n",cas++);
        else printf("Case %d: Strong\n",cas++);
    }
    return 0;
}

E - 简单的图论问题?】 http://acm.hust.edu.cn/vjudge/contest/130626#problem/E

【题意】中文题目

【解题方法】优先队列bfs加上一个记录方向就行啦。

【AC 代码】

#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn = 505;
const int maxm = 505;
int maze[maxn][maxm];
int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
int n,m,r1,c1,r2,c2;
bool vis[maxn][maxm];
bool vis1[maxn][maxm][4];
struct node{
    int x,y,step;
    int d;
    bool operator<(const node &rhs)const{
        return step>rhs.step;
    }
};
int ans1,ans2;
int bfs1()
{
    memset(vis,0,sizeof(vis));
    priority_queue<node>que;
    node now,nex;
    now.x=r1,now.y=c1,now.step=maze[r1][c1];
    vis[r1][c1]=1;
    que.push(now);
    while(!que.empty())
    {
        now=que.top();
        que.pop();
        for(int i=0; i<4; i++)
        {
            int dx=now.x+dir[i][0];
            int dy=now.y+dir[i][1];
            if(dx<1||dx>n||dy<1||dy>m) continue;
            if(maze[dx][dy]==-1) continue;
            if(vis[dx][dy]) continue;
            nex.x=dx,nex.y=dy,nex.step=now.step+maze[dx][dy];
            if(nex.x==r2&&nex.y==c2) return nex.step;
            que.push(nex);
            vis[nex.x][nex.y]=1;
        }
    }
    return -1;
}

int bfs2()
{
    memset(vis1,0,sizeof(vis1));
    priority_queue<node>que;
    node now,nex;
    now.x=r1,now.y=c1,now.step=maze[r1][c1];
    now.d=-1;
    que.push(now);
    while(!que.empty())
    {
        now=que.top();
        que.pop();
        for(int i=0; i<4; i++)
        {
            int dx=now.x+dir[i][0];
            int dy=now.y+dir[i][1];
            if(dx<1||dx>n||dy<1||dy>m) continue;
            if(maze[dx][dy]==-1) continue;
            if(now.d!=i&&!vis1[dx][dy][i]){
                nex.x=dx,nex.y=dy,nex.step=now.step+maze[dx][dy];
                nex.d=i;
                if(nex.x==r2&&nex.y==c2) return nex.step;
                que.push(nex);
                vis1[dx][dy][i]=1;
            }
        }
    }
    return -1;
}

char ss[2000];
int main()
{
    int cas=1;
    while(scanf("%d%d%d%d%d%d",&n,&m,&r1,&c1,&r2,&c2)!=EOF)
    {
        getchar();
        int j;
        for(int i=1; i<=n; i++)
        {
            j=1;
            gets(ss);
            int temp=0;
            int len=strlen(ss);
            for(int k=0; k<len; k++)
            {
                if(ss[k]=='*'){
                    maze[i][j++]=-1;
                    temp=0;
                }
                else if(isdigit(ss[k])){
                    temp=temp*10+(ss[k]-'0');
                }
                else if(ss[k]==' '){
                    if(temp==0) continue;
                    maze[i][j++]=temp;
                    temp=0;
                }
            }
            if(temp) maze[i][j++]=temp;
        }
       ans1=bfs1();
       ans2=bfs2();
       printf("Case %d: %d %d\n",cas++,ans1,ans2);
    }
    return 0;
}

F - 阶乘除法】http://acm.hust.edu.cn/vjudge/contest/130626#problem/F

【题意】中文题目

【解题方法】容易知道只有1的时候无解,其他情况只需要暴力找一下就行啦。

【AC 代码】

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
bool judge(int i,int k)
{
    while(k%i==0)
    {
        k/=i;
        if(k==1) break;
        i++;
    }
    if(k==1) return 1;
    else return 0;
}
int getans(int i,int kk)
{
    int cnt=0;
    while(kk%i==0)
    {
        kk/=i;
        i++;
        cnt++;
        if(kk==1) break;
    }
    return cnt;
}
int main()
{
    int k;
    int cas=1;
    while(scanf("%d",&k)!=EOF)
    {
        int ans=-1;
        if(k==1)
        {
            printf("Case %d: Impossible\n",cas++);
            continue;
        }
        for(int i=2; i<=1000000000; i++)
        {
            if(judge(i,k)){
                ans=i;
                break;
            }
        }
        if(ans==-1)
        {
            printf("Case %d: Impossible\n",cas++);
        }
        else{

            int cnt=getans(ans,k);
            ans--;
            printf("Case %d: %d %d\n",cas++,ans+cnt,ans);
        }
    }
    return 0;
}

H - 聊天止于呵呵】 http://acm.hust.edu.cn/vjudge/contest/130626#problem/H

【题意】中文题目

【解题方法】模拟

【AC 代码】

#include <map>
#include <string>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
map<pair<string,string>,int>mp;
bool check(string s)
{
    int now=0;
    int len=s.size();
    if(len%2!=0) return false;
    for(int i=0; i<len; i+=2)
    {
        if(s[i]!='h'||s[i+1]!='e') return false;
        else now++;
    }
    if(now>1) return true;
    else return false;
}
char s[1010];
struct node{
    string s1,s2;
    char ans[1010];
}t[110];
bool solve(char *T)
{
    int len=strlen(T);
    int i=0;
    while(i<len)
    {
        if(s[i]==':') break;
        i++;
    }
    string temp="";
    i++;i++;
    for(; i<len ; i++)
    {
        if(!isalpha(T[i])){
            T[i]=' ';
            if(check(temp)) return true;
            temp="";
        }
        else if(T[i]==' '){
            if(check(temp)) return true;
            temp="";
        }
        else{
            if(isupper(T[i])) temp+=tolower(T[i]);
            else temp+=T[i];
        }
    }
    if(temp!=""&&check(temp)) return true;
    return false;
}
int main()
{
    int cnt=0;
    int tot=0;
    mp.clear();
    while(gets(s))
    {
        string temp1="",temp2="";
        bool flag=0;
        for(int i=0; s[i]!=':'; i++)
        {
            if(s[i]=='>') continue;
            else if(s[i]=='-'){
                flag=1;
            }
            else if(flag==0) temp1+=s[i];
            else if(flag==1) temp2+=s[i];
        }
        if(temp1>temp2) swap(temp1,temp2);
        if(mp[make_pair(temp1,temp2)]==1){
            for(int i=1; i<=cnt; i++)
            {
                if((t[i].s1==temp1&&t[i].s2==temp2)||(t[i].s1==temp2&&t[i].s2==temp1))
                {
                    strcpy(t[i].ans,s);
                    break;
                }
            }
        }
        else{
            mp[make_pair(temp1,temp2)]=1;
            strcpy(t[++cnt].ans,s);
            t[cnt].s1=temp1,t[cnt].s2=temp2;
        }
    }
    //
    for(int i=1; i<=cnt; i++)
    {
        if(solve(t[i].ans)) tot++;
    }
    double ans=tot*1.0/cnt;
    ans=ans*100+0.5;
    int aa=ans;
    printf("%d%%\n",aa);
    return 0;
}

J - 又一道简单题】 http://acm.hust.edu.cn/vjudge/contest/130626#problem/J

【题意】中文题目。

【解题方法】模拟,水题。

【AC 代码】

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int f[80],cnt;
void init()
{
    for(int i=30; i<=100; i++)
    {
        f[++cnt]=i*i;
    }
}
bool isok(int x)
{
   int xx=sqrt(x);
   if(xx*xx==x)
   {
       return 1;
   }
   return 0;
}
bool vis[10000];
int main()
{
    cnt=0;
    init();
    int T,cas=1,n;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        int ans=0;
        int a=n/1000,b=n/100%10,c=n%100/10,d=n%10;
        memset(vis,false,sizeof(vis));
        for(int i=0; i<=9; i++)
        {
            if(i==a||i==0) continue;
            if(isok(i*1000+b*100+c*10+d)&&!vis[i*1000+b*100+c*10+d]) ans++,vis[i*1000+b*100+c*10+d]=1;
        }
        for(int i=0; i<=9; i++)
        {
            if(i==b) continue;
            if(isok(a*1000+i*100+c*10+d)&&!vis[a*1000+i*100+c*10+d]) ans++,vis[a*1000+i*100+c*10+d]=1;
        }
        for(int i=0; i<=9; i++)
        {
            if(i==c) continue;
            if(isok(a*1000+b*100+i*10+d)&&!vis[a*1000+b*100+i*10+d]) ans++,vis[a*1000+b*100+i*10+d]=1;
        }
        for(int i=0; i<=9; i++)
        {
            if(i==d) continue;
            if(isok(a*1000+b*100+c*10+i)&&!vis[a*1000+b*100+c*10+i]) ans++,vis[a*1000+b*100+c*10+i]=1;
        }
        printf("Case %d: %d\n",cas++,ans);
    }
    return 0;
}



  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值