模擬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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章