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

 

posted @ 2013-05-06 10:21  yefeng1627  阅读(461)  评论(0编辑  收藏  举报

Launch CodeCogs Equation Editor