模拟6月7日

题目描述

jyx和cyy打赌,比谁24点算得快,算得慢的那个人请客。24点的规则是这样的:给定4个1..9的整数,用括号改变运算顺序,通过加、减、乘、除中的一系列运算,得到整数24。注意所有中间结果必须是整数(例如(2*2)/4是允许的,而2*(2/4)是不允许的)。为了赢得这个比赛,请写一个程序帮助我作弊,快速地计算出24点。

输入输出格式

输入格式:

一行4个整数,为给定的4个数字。输入数据保证有解。

输出格式:

一行,以字符串的形式输出结果。注意将每一步的运算的括号补齐(例如(3+5)+6和3* (5+6))。如果有多种解答,输出字典顺序最小的一个。

输入输出样例

输入样例#1: 复制
2 3 5 7 
输出样例#1: 复制
(((3*5)+2)+7)

题目很冗杂;


1/关于字典序的问题我们发现对括号有三种种情况:(((a+b)+c)+d)或((a+b)+(c+d))或(a+(b+(c+d))) 然后会发现第一种和第三种其实是完全等效的。左,中,右,三种;字典序优先,所以选择第一种;

那么有两种入选(((a+b)+c)+d)或((a+b)+(c+d));

第一种是从头到尾算下来,第二种先前两个算,接着后两个算,最后两边得到的结果算在一起;

两种情况要分开打,麻烦没办法;

2/数字和运算符交替搜索是很难想到的;dfs中带一个参数是选择是数字还是字符的,如果是ture则为数字,反之为运算符;

3。用了哈希,搜索记录的是运算符的下标;用一个函数来运算;

4/出现不能除进ruturn;

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int q1[20],q2[20];
char hash[5]={0,'*','+','-','/'};
int n[5];int used[5];
int operate(int a,int b,int c)
{
    switch(c)
    {
        case 1:return a*b;
        case 2:return a+b;
        case 3:return a-b;
        case 4:if(a%b==0)return a/b;else return -10;
    }
    return -10;
}
void dfs1(int u,bool o);
void dfs2(int u,bool o);
int main()
{
    for(int i=1;i<=4;i++)scanf("%d",&n[i]);
    sort(n+1,n+5);
    dfs1(1,1);dfs2(1,1);
    return 0;
}
void dfs1(int u,bool o)
{
    if(u==8)
    {
        int ans=operate(q1[1],q1[3],q2[2]);
        if(ans==-10)return ;
        ans=operate(ans,q1[5],q2[4]);
        if(ans==-10)return ;
        ans=operate(ans,q1[7],q2[6]);
        if(ans==24)
        {
            printf("(((%d%c%d)%c%d)%c%d)",q1[1],hash[q2[2]],q1[3],hash[q2[4]],q1[5],hash[q2[6]],q1[7]);
             exit(0);
        }
    }
    else
    if(o)
    {
        for(int i=1;i<=4;i++)
        if(!used[i])
        {
            q1[u]=n[i];
            used[i]=1;
            dfs1(u+1,!o);
            used[i]=0;//!!!1
        }
    }
    else
    {
        for(int i=1;i<=4;i++)
        {
            q2[u]=i;
            dfs1(u+1,!o);
        }
    }
}
void dfs2(int u,bool o)
{
    if(u==8)
    {
        int ans1=operate(q1[1],q1[3],q2[2]);
        if(ans1==-10)return ;
        int ans2=operate(q1[5],q1[7],q2[6]);
        if(ans2==-10)return ;
        int ans=operate(ans1,ans2,q2[4]);
        if(ans==24)
        {
            printf("((%d%c%d)%c(%d%c%d))",q1[1],hash[q2[2]],q1[3],hash[q2[4]],q1[5],hash[q2[6]],q1[7]);
            exit(0);
        }
    }
    else
    if(o)
    {
        for(int i=1;i<=4;i++)
        if(!used[i])
        {
            q1[u]=n[i];
            used[i]=1;
            dfs2(u+1,!o);
            used[i]=0;
        }
    }
    else
    {
        for(int i=1;i<=4;i++)
        {
            q2[u]=i;
            dfs2(u+1,!o);
        }
    }
}

亲手打的,懒得标注了

题目描述

在一个长方形框子里,最多有N(0≤N≤6)个相异的点,在其中任何一个点上放一个很小的油滴,那么这个油滴会一直扩展,直到接触到其他油滴或者框子的边界。必须等一个油滴扩展完毕才能放置下一个油滴。那么应该按照怎样的顺序在这N个点上放置油滴,才能使放置完毕后所有油滴占据的总体积最大呢?(不同的油滴不会相互融合)

注:圆的面积公式V=pi*r*r,其中r为圆的半径。

输入输出格式

输入格式:

第1行一个整数N。

第2行为长方形边框一个顶点及其对角顶点的坐标,x,y,x’,y’。

接下去N行,每行两个整数xi,yi,表示盒子的N个点的坐标。

以上所有的数据都在[-1000,1000]内。

输出格式:

一行,一个整数,长方形盒子剩余的最小空间(结果四舍五入输出)

输入输出样例

输入样例#1: 复制
2
20 0 10 10
13 3
17 7
输出样例#1: 复制
50

因为没有单独讨论油滴在另一个油滴扩展的圆内的情况,这种情况就不能扩展,不单独讨论会变成负面积


#include<bits/stdc++.h>
using namespace std;
double dis[10][10],x,y,x2,y2,a[10][4];//a为点的坐标,1为横坐标,2为纵坐标,dis油滴间距
double R[100],r,maxn;//r为准备放置的油滴的扩散半径 ,maxn是最大油面积
int vis[100],n;//vis判断是否走过
const double pi=acos(-1);
void dfs(int steps,double s)//steps位当前步数,s为当前面积
{
    if(steps==n+1)//油滴放完了
    {  //更新最大值
    if(s>maxn) maxn=s;}
    else
        for(int k=1;k<=n;k++)
            if(!vis[k])//如果没拜访过
            {
                //矩形和已放置的油滴约束了r的大小 //fabs绝对值函数可以计算浮点数,好像abs不行
                r=fabs(y2-a[k][2]);//纵坐标边框限制
                //找到所有限制下的最小半径
                if(r>fabs(y-a[k][2]))r=fabs(y-a[k][2]);//另一边
                if(r>fabs(x2-a[k][1]))r=fabs(x2-a[k][1]);//其他边框
                if(r>fabs(x-a[k][1]))r=fabs(x-a[k][1]);//还是边
                for(int i=1;i<=n;i++)
                {
                    if(vis[i])//如果拜访过了
                        if(r>dis[k][i]-R[i])r=dis[k][i]-R[i];//其他油滴限制,油滴距离减去已存半径
                }
                r=r<0?0:r; //r不能为负 
                R[k]=r;//记录半径
                //搜索模板
                vis[k]=1;
                dfs(steps+1,s+pi*r*r);
                vis[k]=0;
                R[k]=0.0;
            }
}
int main()
{
    scanf("%d%lf%lf%lf%lf",&n,&x,&y,&x2,&y2);
    for(int i=1;i<=n;i++)scanf("%lf%lf",&a[i][1],&a[i][2]);
        //预处理出油滴间距dis 
    for(int i=1;i<=n;i++)  
    {
        for(int j=1;j<=i;j++)
        {
            dis[i][j]=sqrt(pow(fabs(a[i][1]-a[j][1]),2)+pow(fabs(a[i][2]-a[j][2]),2));//油滴i和油滴j之间的间距,距离公式
            dis[j][i]=dis[i][j];//i到j的距离就是j到i的距离
        }
    }
    double S=fabs(x-x2)*fabs(y-y2);//矩形面积 
    dfs(1,0.0);
    printf("%.0lf",floor(S-maxn+0.5));
    return 0;
}

猜你喜欢

转载自blog.csdn.net/k42946/article/details/80614012
今日推荐