2013-5-3 NEERC 2012, Eastern subregional contest

A:  相邻三个和最大,及对应中间位置.  暴力即可.

View Code
#include <iostream>

#include <cmath>

#include <cstring>

#include <cstdio>

#include <string>

#include <stdlib.h>

#include <algorithm>

using namespace std;

typedef long long LL;

const LL Mod= 1e9+7;



const int N = 1010;

int a[N], n;

 

int main( )

{

    while( scanf("%d",&n)!=EOF ){

        for(int i = 0; i < n; i++ ) scanf("%d",a+i);

        int res = -1, idx; 

        for(int i = 0; i < n-2; i++ ){

            int t = 0;

            for(int j = i; j <= i+2; j++ )

                t += a[j];

            if( t > res )

             res = t, idx = i+1; 

        } 

        printf("%d %d\n", res , idx+1 );

    }

    return 0;

}

 

B:  题意不明.

C: 题意不明.

D: 题意不明.

E: 同上

F: 主要是复制操作,注意观察, 操作数只有 10^6, 意味着栈中元素超过2n后,复制操作没有效果了.这里就可以忽视复制了.否则用memcpy即可.

View Code
#include<cstdio>

#include<cstring>

#include<cstdlib>

#include<algorithm>

using namespace std;



const int N = (int)1e6+100;



int a[N<<2], n;



int main(){

    while( scanf("%d",&n) != EOF){

        int l = 0, r = -1;

        for(int i = 0; i < n; i++){

            int x; scanf("%d", &x);

            if( x > 0 ) a[++r] = x;

            else if( x == -1 ) printf("%d\n", a[r--] );

            else{

                if( (r+l-1) >= n ) continue;    

                memcpy( a+r+1, a+l, (r-l+1)*sizeof(int));    

                r = r+(r-l+1);    

            }

        }

    }    

    return 0;

}

 

G: 题意不明

H: 好神奇的题意... 给定生命上限P, 用威力为K的技能打掉 所有小于K的棋子,反弹伤害为 num*K, 明白了这个贪心即可.

View Code
#include<cstdio>

#include<cstring>

#include<algorithm>

#include<cstdlib>

#include<map>

using namespace std;



const int N = 1010;



int a[N], n, p;

map<int,int> mp;



int main(){

    while( scanf("%d%d", &n,&p) != EOF){

        mp.clear();    

        for(int i = 0; i < n; i++){

            scanf("%d",&a[i]);

            if( mp.count(a[i]) == 0 )

                mp[a[i]] = 1;

            else mp[a[i]]++;

        }

        sort( a, a+n );

        n = unique(a,a+n)-a;

        int n1 = 0, n2 = 0;    

        int i = 0;

        while( i < n ){

            if( p >= mp[a[i]]*a[i] ){

                int j = i, t = 0;

                while( (j<n) && (p>=a[j]*(t+mp[a[j]])) )

                    t += mp[a[j]], j++; 

                for(int k = i; k < j; k++)

                    n1 += mp[ a[k] ];

                n2++;

                i = j;    

            }    

            else break;    

        }    

        printf("%d %d\n", n1, n2 );    

    }

    return 0;

}

 

I: 题意不明

J: 同上 

K: 题目可转换成从一个点出发走M步回来, 输出路径. 当M为奇数或者M大于格子总数量不可行,其他情况都有解.

接下来就是构造一个符合条件的解了.我们设定起点为(1,1) ,这里要分两总情况:

  当 N是偶数,则N*N也是偶数,可以通过 保留第一列,然后 [2,N] 走Z字形,总是能得出解.因为是成对的.

  当 N是奇数,则N*N也是奇数, 则 保留一列,走Z字,是不行的,因为Z字不成对,  不过我们可以保留 2列,以及最后两行,

来走Z字, 然后四个相邻绕圈即可..

View Code
#include<cstdio>

#include<cstring>

#include<cstdlib>

#include<algorithm>

using namespace std;

const int N = 110;



bool vis[N][N];

int n, m;

int cnt[N*N];

int dir[4][2]={{0,-1},{0,1},{1,0},{-1,0}};

bool flag;

bool legal(int x,int y){

    if(x>=0&&x<n&&y>=0&&y<n)

        return true;

    return false;

}

void dfs(int x,int y,int f,int L){

    if( flag ) return;

    if( L == m ){

        if( (x==0) && (y==0) ) flag = true;    

        return ;

    }

    else{

        for(int i = 0; i < 4 && !flag; i++){

            int xx = dir[i][0]+x, yy = dir[i][1]+y;    

            if( legal(xx,yy) && (!vis[xx][yy]) && (xx*n+yy != f) ){

                if( (((xx+yy)&1) != ((m-L-1)&1)) || ((xx+yy)>(m-L-1)) ) continue;

                vis[xx][yy] = true;

                cnt[L] = xx*n+yy;

                dfs( xx,yy,x*n+y,L+1);

                vis[xx][yy] = false;

            }

        }    

    }

}

void solve(){

    int L = m-1, k;

    int x = 2, y = 1;

    while( 1 ){

        k = 2*n+y-2;

        if( L > k ){    

            for(int i = x; i <= n; i++)

                printf("%d %d\n", i, y );

            for(int i = n; i >= x; i--)

                printf("%d %d\n", i, y+1);

            L -= (2*n-2);

            y += 2;

        }

        else{

            //printf("x = %d, y = %d\n", x, y );    

            //printf("k = %d, L = %d\n", k , L );    

            int a = (k-L)/2;

            if( L == y ){

                printf("%d %d\n", x, y );

                for(int i = y; i > 1; i-- )

                    printf("1 %d\n", i);

            }    

            else{

                for(int i = x; i <= n-a; i++)

                    printf("%d %d\n", i, y);

                for(int i = n-a; i >= x; i--)

                    printf("%d %d\n", i, y+1);

                for(int i = y+1; i > 1; i--)

                    printf("1 %d\n", i );

            }    

            break;    

        }    

    }

}

void gao(){

    for(int i = 2; i <= n; i++)

        printf("1 %d\n", i );

    int x = 2, y = n, L = n*n-m;

    for(int k = 1; k <= (n-2)/2; k++){

        for(int i = y; i >= 3; i--)

            printf("%d %d\n", x, i );

        for(int i = 3; i <= y; i++)

            printf("%d %d\n", x+1, i );

        x += 2;

    }

    int yy = y;    

    while( yy > L ){

        printf("%d %d\n", x, yy);

        printf("%d %d\n", x+1, yy);

        printf("%d %d\n", x+1, yy-1);

        printf("%d %d\n", x, yy-1);

        yy -= 2;    

    }    

    for(int i = yy; i >= 1; i-- )

        printf("%d %d\n", x, i );

    x = n-2, y = 1;    

    for(int k = 1; k <= (n-3)/2; k++){

        printf("%d %d\n", x, y );

        printf("%d %d\n", x, y+1);

        printf("%d %d\n", x-1, y+1);

        printf("%d %d\n", x-1, y);

        x -= 2;

    }

}

int main(){

    while( scanf("%d%d", &n,&m) != EOF){

        if( (m>n*n)||((m&1)) )

            puts("Unsuitable device");

        else{

            puts("Overwhelming power of magic");

            puts("1 1");    

            if( !(n&1) || (n<3) || (m<=n*(n-1)+2) )     

                solve();    

            else    gao();    

        }

    }

    return 0;

}

 

你可能感兴趣的:(test)