codeforce 277div2

life4711發表於2014-11-12

http://codeforces.com/contest/486

A注意long long

#include <stdio.h>
#include <iostream>
using namespace std;
typedef long long LL;
LL n;
int main()
{
    while(~scanf("%lld",&n))
    {
        LL f;
        if(n&1)
            f=n/2-n;
        else
            f=n/2;
        printf("%lld\n",f);
    }
    return 0;
}

B

/**
CF 277B
思路:首先將要求陣列置1,對於給出的陣列若a[i][j]為0,就將要求陣列i行j列全置零。
      最後所有的0都置完後,cnt賦1,重新遍歷一遍給出陣列,看是否對於a[i][j]==1時對應i行j列的元素全為0,是則cnt==0,
      遍歷完後cnt==0則NO,否則YES最後輸出此時的要求陣列即可
*/
#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
int a[102][102],b[105][105];
int n,m;
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        for(int i=0; i<n; i++)
            for(int j=0; j<m; j++)
                b[i][j]=1;
        int cnt=1;
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<m; j++)
            {
                scanf("%d",&a[i][j]);
                if(a[i][j]==0)
                {
                    for(int k=0; k<n; k++)
                        b[k][j]=0;
                    for(int k=0; k<m; k++)
                        b[i][k]=0;
                }

            }
        }
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<m; j++)
            {
                if(a[i][j]==1)
                {
                    int flag=0;
                    for(int k=0; k<n; k++)
                        if(b[k][j]==1)
                            flag=1;
                    for(int k=0; k<m; k++)
                        if(b[i][k]==1)
                            flag=1;
                    if(flag==0)
                        cnt=0;
                }
            }
        }
        if(cnt==0)
            puts("NO");
        else
        {
            puts("YES");
            for(int i=0; i<n; i++)
            {
                for(int j=0; j<m; j++)
                {
                    printf(j==m-1?"%d\n":"%d ",b[i][j]);
                }
            }
        }
    }
}


C

/**
CF 277C
思路:先不算移動的步數,只處理字串的前一半,使其與後一半對應,求出所有字元都對應後需要的最小步數sum1,在這個過程中標記所有需改變的位置。
      從m位置(由於我們處理的前一半如果m>n/2,m=n+1-m)開始移動,分別考慮num[0]和num[k-1]和m的幾種位置的相對關係,求出最小的移動步數sum2.sum12即為所求
      這題還是有一些細節需要注意的,見程式碼註釋。
      
**/
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
using namespace std;
int a[100005],num[100005];
int n,k,m;
long long sum;
int abs(int x)
{
    if(x>0)
        return x;
    return -x;
}
int main()
{
    while(~scanf("%d%d%*c",&n,&m))
    {
        if(m>n/2)//細節1
            m=n-m+1;
        for(int i=1;i<=n;i++)
        {
            char t;
            scanf("%c",&t);
            a[i]=t-'a'+1;
        }
        sum=0;
        k=0;
        for(int i=1;i<=n/2;i++)
        {
            if(a[i]!=a[n+1-i])
            {
               int t=abs(a[n+1-i]-a[i]);
               sum+=min(26-t,t);//細節2
               //printf("(%d)\n",min(26-t,t));
               num[k++]=i;
            }
        }
      //  printf("%lld\n",sum);
        if(k==0)
        {
            printf("0\n");
            continue;
        }
        if(num[k-1]<=m&&num[0]<=m)
               sum+=m-num[0];
        else if(num[k-1]>=m&&num[0]>=m)
               sum+=num[k-1]-m;
        else
        {
            //printf("***\n");
            int x=min(m-num[0]+num[k-1]-num[0],num[k-1]-m+num[k-1]-num[0]);//細節3
            x=min(x,min(m-num[0]+n-num[k-1]+1,n-m+num[0]));//細節4
            sum+=x;
        }
        printf("%lld\n",sum);
       /*for(int i=0;i<k;i++)
            printf("%d ",num[i]);
        printf("\n");*/
    }
    return 0;
}