Codeforces Round #228 (Div. 2)
分类:
IT文章
•
2025-01-30 16:20:31
A. Fox and Number Game
题意:有 n 个数, 每次找一对 i , j 满足a[i] > a[j],然后 a[i] = a[i] - a[j],问最后剩下的数的和最小是多少。
分析: 每次找最小的数,看看哪些数比它大,然后减去,直到所有数相等。
/****************************************
* File Name: 228d2a.cpp
* Author: sky0917
* Created Time: 2014年02月 5日 13:32:03
****************************************/
#include <map>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 102;
int a[maxn];
int main(){
int n;
while (scanf("%d",&n)!=EOF){
for (int i=0; i<n; i++)
scanf("%d",&a[i]);
while (1){
int d = a[0];
for (int i=1; i<n; i++){
if (a[i] < d)
d = a[i];
}
int f = 1;
for (int i=0; i<n; i++){
if (a[i] > d){
a[i] -= d;
f = 0;
}
}
if (f) break;
}
int sum = 0;
for (int i=0; i<n; i++)
sum += a[i];
printf("%d
",sum);
}
return 0;
}
View Code
B. Fox and Cross
题意:有个grid,里面有 "#" 和 “." ,问是否可以找到一些十字,如下:
#
###
#
把grid 中的 # 全部覆盖,并且不能相交。
分析:从上往下,从左往右,遍历方格,第一次遇到的"#" 一定是十字的最上方那个部分,看看是不是合法的十字,然后把这个十字全部标记掉。
最后看看grid 中是否有没有标记的 #。
/****************************************
* File Name: 228d2b.cpp
* Author: sky0917
* Created Time: 2014年02月 5日 13:42:30
****************************************/
#include <map>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 102;
char s[maxn];
int g[maxn][maxn];
int main(){
int n;
while (scanf("%d",&n)!=EOF){
for (int i=0; i<n; i++){
scanf("%s",s);
for (int j=0; s[j]; j++){
g[i][j] = (s[j]=='#'?1:0);
}
}
int f = 1;
for (int i=0; i<n-2 && f; i++){
for (int j=1; j<n-1 && f; j++){
if (g[i][j]){
int sum = g[i+1][j] + g[i+2][j] + g[i+1][j-1] + g[i+1][j+1];
if (sum == 4){
g[i][j] = g[i+1][j] = g[i+2][j] = g[i+1][j-1] = g[i+1][j+1] = 0;
}
else f = 0;
}
}
}
for (int i=0; i<n && f; i++){
for (int j=0; j<n && f; j++){
if (g[i][j]) f = 0;
}
}
printf("%s
",f?"YES":"NO");
}
return 0;
}
View Code
C. Fox and Box Accumulation
题意:有 n 个盒子,每个盒子有一个属性,si, 表示这个盒子上方能连续放的盒子的数目,每个盒子形状相同,如果一些盒子能摞在一起就称为一堆,
问怎样摞,最后的堆数最少。
分析:二分 + 贪心。
先对盒子按si 大小排序,大的尽量放下面,二分枚举最后的堆数 k;
把盒子从大到小依次放在第 1。。。k 堆,构成最底层,然后在从大到小放好第二层,看看最后能否把盒子放完。
/****************************************
* File Name: 228a.cpp
* Author: sky0917
* Created Time: 2014年02月 3日 23:28:25
****************************************/
#include <map>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 105;
const int INF = 0x1f1f1f1f;
int n, m;
int a[maxn];
int b[maxn];
int h[maxn];
bool ok(int x){
sort(a, a+n);
memset(h, INF, sizeof(h));
for (int i=n-1; i>=0; i--){
int u = i % x;
if (h[u] == 0)
return false;
h[u] = min(h[u]-1, a[i]);
}
return true;
}
void solve(){
int l = 1, r = n, mid;
int res;
while (l <= r){
mid = (l+r)>>1;
if (ok(mid)){
r = mid-1;
res = mid;
}
else{
l = mid+1;
}
}
printf("%d
",res);
}
int main(){
while (scanf("%d",&n)!=EOF){
for (int i=0; i<n; i++){
scanf("%d",&a[i]);
}
solve();
}
return 0;
}
View Code
题意: 给出一个 k 表示最短路的个数。要求构造出一个节点不大于1000的无向图,使得其最短路的个数为 k ,无向图的边长为1.
分析:可以把 k 看成二进制数,如 k = 100100. 那么 k = 2^5 + 2^2;
/****************************************
* File Name: 228b.cpp
* Author: sky0917
* Created Time: 2014年02月 4日 12:28:25
****************************************/
#include <map>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1001;
int K;
int d[maxn];
int g[maxn][maxn];
int tp;
inline void mark(int x, int y){
g[x][y] = g[y][x] = 1;
}
void solve(){
memset(g, 0, sizeof(g));
tp = 0;
while (K){
d[tp++] = K % 4;
K /= 4;
}
int n = 2;
for (int i=0; i<tp; i++){
if (d[i]){
n += d[i] + i * 4 + (tp-i-1);
}
}
printf("%d
",n);
int cnt = 2;
int st;
for (int i=0; i<tp; i++){
if (d[i] != 0){
if (i != tp-1){
if (tp != 1){
mark(0, cnt);
cnt++;
for (int j=1; j<tp-i-1; j++){
mark(cnt-1, cnt);
cnt++;
}
}
}
if (i == 0){
st = cnt-1;
if (tp == 1)
st = 0;
for (int j=0; j<d[i]; j++)
mark(st, cnt+j);
st = cnt;
cnt += d[i];
for (int j=st; j<st+d[i]; j++)
mark(j, 1);
continue;
}
st = cnt-1;
if (i == tp-1)
st = 0;
if (d[i] == 1){
mark(st, cnt);
}
else if (d[i] == 2){
mark(st, cnt);
mark(st, cnt+1);
}
else if (d[i] == 3){
mark(st, cnt);
mark(st, cnt+1);
mark(st, cnt+2);
}
st = cnt;
cnt += d[i];
for (int j=st; j<cnt; j++){
for (int k=0; k<4; k++){
mark(j, cnt+k);
}
}
st = cnt;
cnt += 4;
for (int j=1; j<i; j++){
for (int l=0; l<4; l++){
for (int k=st; k<st+4; k++){
mark(k, cnt+l);
}
}
st = cnt;
cnt += 4;
}
for (int j=st; j<st+4; j++){
mark(j, 1);
}
}
}
for (int i=0; i<n; i++){
for (int j=0; j<n; j++){
if (g[i][j])putchar('Y');
else putchar('N');
}
puts("");
}
}
int main(){
while (scanf("%d",&K)!=EOF){
solve();
}
return 0;
}