Codeforces Round #194(Div.2) ABCD 题解

作业题,写了2天(的晚上)
比赛链接:http://codeforces.com/contest/334

A. Candy Bags

睿智题,注意实现,每次对于 1..n 1.. n 答案存上当前序列的首位 2 2 个,我是用一个二维数组存的答案,时间复杂度O(n2)

// by Balloons
#include <cstdio>

int n;
int a[2005][2005],cnt[2005];

int main(){
    int now=1;
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++)a[j][++cnt[j]]=now,a[j][++cnt[j]]=n*n-now+1,++now;
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++)printf("%d ",a[i][j]);
        puts("");
    }

    return 0;
}

B.Eight Point Sets

睿智题,一些判断即可

// by Balloons
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define mpr make_pair
#define debug() puts("okkkkkkkk")
#define rep(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)

using namespace std;

typedef long long LL;

const int inf = 1 << 30;

const int maxn=15;
struct coor{
    int x,y;
}a[maxn];
int n=8;

int cmp(coor a,coor b){
    if(a.x==b.x)return a.y<b.y;
    return a.x<b.x;
}

inline void fail(){puts("ugly");exit(0);}
inline void success(){puts("respectable");exit(0);}

int main(){
    rep(i,1,n)scanf("%d%d",&a[i].x,&a[i].y);
    sort(a+1,a+n+1,cmp);
//  for(int i=1;i<=n;i++)printf("%d %d\n",a[i].x,a[i].y);

    if(a[1].x==a[2].x&&a[2].x==a[3].x&&a[4].x==a[5].x&&a[6].x==a[7].x&&a[7].x==a[8].x);
    else fail();
    if(a[1].y==a[4].y&&a[4].y==a[6].y&&a[2].y==a[7].y&&a[3].y==a[5].y&&a[5].y==a[8].y);
    else fail();
    if(a[1].x<a[4].x&&a[4].x<a[6].x);
    else fail();
    if(a[1].y<a[2].y&&a[2].y<a[3].y&&a[4].y<a[5].y&&a[6].y<a[7].y&&a[7].y<a[8].y);
    else fail();

    success();

    return 0;
}

C.Secrets

题意题+思维题(感觉有出 noip d1t1 n o i p   d 1 t 1 的可能啊>_<)
题目大意:一个国家只发行 3n(n0) 3 n ( n ≥ 0 ) 面额的硬币,有一个人去买了 n n 元东西,发现无法正好凑出n,问在凑出的钱 >n > n 且面额最小的情况下最少花多少个硬币?

我的做法是:
首先一定不会有 1 1 元的硬币(因为这样就能正好凑出 n 了)
先考虑 n mod 30 n   m o d   3 ≠ 0 的情况,显然可以用 3 3 元凑,一定凑不出来且硬币数量最大,答案即为n/3+1
继续考虑当 n mod 3==0 n   m o d   3 == 0 的情况,有一个显然的结论: a a 3的倍数,那么在花硬币最多的前提下, ans(a)==ans(3a) a n s ( a ) == a n s ( 3 a ) ,因为这样只需要将每个硬币面额 3 ∗ 3 即可
这样做法就比较显然了,求出 n n 的三进制下最低不为0的位(lowbit()的既视感2333)为第 x x 位,答案就是n/3x+1,实现可以每次除 3 3 即可

// by Balloons
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define mpr make_pair
#define debug() puts("okkkkkkkk")
#define rep(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)

using namespace std;

typedef long long LL;

const int inf = 1 << 30;

LL n;
// (220)3 = 24 1:27
// (120)3 = 15 2:9+9 
// (10)3 = 3

int main(){
    scanf("%I64d",&n);
    while(n){
        if(n==1)return puts("1"),0;
        if(n%3)break;
        n/=3;
    }
    printf("%I64d\n",n/3+1);

    return 0;
}

D.Chips

考虑2个非常显然的结论:
1. 如果有一个位置 (x,y) 有障碍,那么第 x x 行和第 y 列一定不可能放棋子
2. 1行或1列有至多有1个棋子

考虑一个性质:如果对应行或列没有障碍,第 i i 行、第i列、第 ni+1 n − i + 1 行、第 ni+1 n − i + 1 列,一定可以构造出一种方案,使这些都有放法

注意 n n <script type="math/tex" id="MathJax-Element-2381">n</script>为奇数的时候,中间那一行和那一列至多放1个。(因为会冲突)
代码很短

// by Balloons
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define mpr make_pair
#define debug() puts("okkkkkkkk")
#define rep(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)

using namespace std;

typedef long long LL;

const int inf = 1 << 30;

const int maxn=1e5+5;
int n,m; 
struct coor{
    int x,y;
}ban[maxn];
int notokx[1005],notoky[1005];

int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        scanf("%d%d",&ban[i].x,&ban[i].y);
        notokx[ban[i].x]=1;notoky[ban[i].y]=1;
    }
    int mid=n/2+1,ans=0;
    for(int i=2;i<=n-1;i++){
        if(n%2==1&&i==mid){
            if(!notokx[mid]||!notoky[mid])++ans;
            break;
        }
        int x1,x2,y1,y2;
        x1=i;x2=n+1-i;y1=x1;y2=x2;
        if(!notokx[x1])++ans;if(!notokx[x2])++ans;
        if(!notoky[y1])++ans;if(!notoky[y2])++ans;
//      printf("%d %d\n",i,ans);
        if(n%2==0&&i==n/2)break;
    }
    printf("%d\n",ans);

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值