特长生模拟——17年东莞特长生考试

序言:

一模爆炸以后,模拟赛也炸了。。。
这次因为心态跟对时间的把握不足,直接导致了失手
估分是100+80+100+100=380
实际是100+50+100+20=270
而去年特长生前10的线是310…
要调整心态,继续努力了…
能拿的分,绝对不丢
难拿的分,尽量去拿
可打的暴力,不能不打

T1,优美景点,题目大意:

给出N个数a1,a2…an,从大到小输出。
1 <=N <= 500
1 <= ai <= 3000

题解:

直接排一下就可以了..

代码:

#include
#include
#include

using namespace std;

int n,a[3005];

int main()
{
    scanf("%d",&n);
    for (int i=1; i<=n; i++) scanf("%d",&a[i]);
    sort(a+1,a+n+1);
    for (int i=n; i>=1; i--) printf("%d\n",a[i]);
    return 0;
}

T2,益智游戏,题目大意:

给定N组数,每组数包括4个1到9之间的自然数,要求判断能否对这4个自然数进行适当的算术运算,使运算结果等于24。
  你可以使用的运算只有:+,-,,/,您还可以使用()来改变运算顺序。注意:所有的中间结果须是整数,所以一些除法运算是不允许的(例如,(2*2)/4是合法的,2(2/4)是不合法的)。下面我们给出一个游戏的具体例子:
  若给出的4个自然数是:1、2、3、7,则一种可能的解答是1+2+3*7=24。计算过程:
  2+1=3
  7*3=21
  21+3=24

题解:

因为这里所用的时间导致我对整体的题目的时间把握不足,
而且后来还是没调出来去做了后面的题,最后匆匆又用了20分钟表一下可能的情况,所以水了50..情况太多了,没考虑齐
而且,我以为4个数的顺序,是固定的…
有个很优秀的做法,
我们以4个数分别为开头的清空,直接搜所有可能,
当前结果是rp,当前选到的数是j
则下一个数可以是
j-rp,rp-j,rp+j,rp*j,rp/j(要满足rp%j=0)
这样子就不用考虑括号了,
因为你当前有些括号使得某些数优先计算,那么你将这些数放在首位以后,情况也是不会被忽略的..

#include
#include
#include
#define N 5

using namespace std;

int n,a[N],b[N];
bool ans;

void dfs(int dep,int rp)
{
    if (ans) return;
    if (rp==4){
       if (dep==24) ans=1;
       return;   
    }
   for (int i=1; i<=4; i++)
        if (b[i]){
            b[i]=0;
            dfs(dep+a[i],rp+1);
            dfs(dep-a[i],rp+1);
            dfs(a[i]-dep,rp+1);
            dfs(dep*a[i],rp+1);
            if (dep%a[i]==0)
                dfs(dep/a[i],rp+1);
            b[i]=1;
        }
}

int main()
{
    scanf("%d",&n);
    for (int k=1; k<=n; k++)
    {
        for (int i=1; i<=4; i++)
            {
                 scanf("%d",&a[i]);
                 b[i]=1;
            } 
        ans=0;
        for (int i=1; i<=4; i++) 
            {
                 b[i]=0;
                 dfs(a[i],1);
                 b[i]=1;
            }
        if (ans) printf("1\n"); 
            else printf("0\n");
    }
}

T3,工程,题目大意:

给出N个工程以及所需要的完成时间,以及每个工程的子工程,问完成整个工程最少要用的时间,如果子工程划分不合理,则输出-1。
在任何时刻可以有任何多个子工程同时在施工,也即同时施工的子工程个数不受限制。

N<=200

题解:

dp+dfs:
f[i]表示第i个工程最少能在第几时刻完成。
然后每次dfs找一下自己的子工程转移即可。

代码:

#include
#include
#include
#define INF 2333333
#define N 205

using namespace std;

int check,n,ans,r[N],c[N],f[N],a[N][N];

void dfs(int dep){
    if (check) return;
    if (c[dep]==2){
        check=1;
        return;
    }
    int rp=0;
    for (int i=1; i<=n; i++) 
         if (a[dep][i]==1){
            if (f[i]==INF){
                c[i]++;
                dfs(i);
                c[i]--;
            }
            rp=max(rp,f[i]);
         }
    f[dep]=rp+r[dep];
}

int main()
{
    scanf("%d",&n);
    for (int i=1; i<=n; i++) scanf("%d",&r[i]);
    for (int i=1; i<=n; i++)
         {
             for (int j=1; j<=n; j++) 
                  if (j!=i) scanf("%d",&a[i][j]);
             f[i]=INF;
         }
    for (int i=1; i<=n; i++)
         if (f[i]==INF)
            {
                 check=0; c[i]=1;
                 dfs(i);
                 if (check) break;
                 c[i]=0;     
                 ans=max(ans,f[i]);
            }
    if (check) printf("-1\n");

       else printf("%d\n",ans);
    return 0;
}

T4,摆渡线路,题目大意:

某市的M公园中有一个近乎圆形的湖,有100个主要景点分布在湖边,为了方便游客,公园在一些景点之间开设了直通的摩托飞艇摆渡的项目一来减少游客在景点到景点之间所花的时间,二来也可以让游客体验一下惊险刺激的摩托飞艇。果然摩托飞艇摆渡项目大为成功,为了充分满足游客需要,摆渡线路越来越多。不料随着线路的增加,危险性也随之增加。如果两个摆渡线路之间有交叉(如上图),在这两个线路上的飞艇一旦发生碰撞,后果将不堪设想。
公园的管理层近日做出决定,本着安全第一的原则,在这个湖上取消一些线路,使剩下的任意两条线路在行驶阶段(即不考虑码头)不交叉。同时,考虑到经济效益,他们要求被取消的线路数最小,即保留尽量多的线路。他们希望你能够帮助他们算一算最多可以保留多少条线路。

1=

题解:

一眼过去石子合并,然后很奇异的凉了。。
发现状态转移很zz的搞了,而正解也很显然,
f[i][j]表示区间[i,j]内的最多保留数。
f[i][j]=max{f[i][k]+f[k][j]}+ 0/1
0/1 为i,j之间是否存在一条边
注意一下
区间[1][5]跟区间[2][4]不冲突,但是如果这样只能转移一个,所以
我们要在[4][2],[5][1]也连一条边
自己手动一下就知道了
时间复杂度:O(100^3)

代码:

#include
#include  
#include
#define modn 100
#define N 105

int f[N][N],n,ans,x,y;  

using namespace std; 

int main() 
{
    scanf("%d",&n);
        for (int i=1; i<=n; i++)
        {
             scanf("%d%d",&x,&y);
             f[x][y]=f[y][x]=1;
        }

        for (int len=1; len<=modn-1; len++)
             for (int i=1; i<=modn; i++)
                 {
                      int j=i+len,cmax=0;
                      for (int k=i+1; k<=j-1; k++) 
                           cmax=max(cmax,f[i][(k-1)%modn+1]+f[(k-1)%modn+1][(j-1)%modn+1]);
                      f[i][(j-1)%modn+1]+=cmax;
                 }
    printf("%d\n",f[1][modn]);
    return 0;
}

你可能感兴趣的:(C++,暴力/枚举/模拟,深搜dfs,动态规划)