作业题,写了2天(的晚上)
比赛链接:http://codeforces.com/contest/334
A. Candy Bags
睿智题,注意实现,每次对于 1..n 1.. n 答案存上当前序列的首位 2 2 个,我是用一个二维数组存的答案,时间复杂度
// 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(n≥0)
3
n
(
n
≥
0
)
面额的硬币,有一个人去买了
n
n
元东西,发现无法正好凑出,问在凑出的钱
>n
>
n
且面额最小的情况下最少花多少个硬币?
我的做法是:
首先一定不会有
1
1
元的硬币(因为这样就能正好凑出 了)
先考虑
n mod 3≠0
n
m
o
d
3
≠
0
的情况,显然可以用
3
3
元凑,一定凑不出来且硬币数量最大,答案即为
继续考虑当
n mod 3==0
n
m
o
d
3
==
0
的情况,有一个显然的结论:
a
a
是的倍数,那么在花硬币最多的前提下,
ans(a)==ans(3a)
a
n
s
(
a
)
==
a
n
s
(
3
a
)
,因为这样只需要将每个硬币面额
∗3
∗
3
即可
这样做法就比较显然了,求出
n
n
的三进制下最低不为0的位(的既视感2333)为第
x
x
位,答案就是,实现可以每次除
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
x
行和第 列一定不可能放棋子
2. 1行或1列有至多有1个棋子
考虑一个性质:如果对应行或列没有障碍,第 i i 行、第列、第 n−i+1 n − i + 1 行、第 n−i+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;
}