您的位置:首页 > 其它

第四届福建省大学生程序设计竞赛

2013-12-23 23:12 369 查看
TagPro.IDProblem TitleRatio(AC/Submit)
 1Forever 0.518.92%(7/37)
 2Sub-Bipartite Graph50.00%(1/2)
 3Center of a Tree0.00%(0/2)
 4Board Game54.55%(6/11)
 5Shooting Game37.84%(14/37)
 6Rock-Paper-Scissors Game50.00%(1/2)
 7Easy Game73.86%(113/153)
 8A-B Game43.46%(103/237)
 9Moon Game22.98%(54/235)
 10Reverse Game40.00%(6/15)
 11Fire Game17.59%(38/216)
 12OOXX Game60.12%(98/163)
现场6题。。赛后想其实能出7题的。。
开始先是切了3题最水的题目。。都是1A

G题:

#include <stdio.h>
#include <string.h>
const int N = 10100;
const char ans[2][10] = {"Even", "Odd"};
int t;
char str
;

int main() {
int cas = 0;
scanf("%d", &t);
while (t--) {
scanf("%s", str);
printf("Case %d: %s\n", ++cas, ans[strlen(str) % 2]);

}
return 0;
}H题:
#include <stdio.h>
#include <string.h>

int t;
long long a, b;

int main() {
int cas = 0;
scanf("%d", &t);
while (t--) {
int ans = 0;
scanf("%lld%lld", &a, &b);
while (a > b) {
a -= (a - 1) / 2;
ans ++;
}
printf("Case %d: %d\n", ++cas, ans);
}
return 0;
}

L题:
#include <stdio.h>
#include <string.h>
const int N = 105;
const char ANS[2][20] = {"Fat brother", "Maze"};
int t;
int n, m;
char str

;

int main() {
int cas = 0;
scanf("%d", &t);
while (t--) {
int ans = 0;
scanf("%d%d", &n, &m);
for (int i = 0; i < n; i ++) {
scanf("%s", &str[i]);
for (int j = 0; j < m; j ++)
if (str[i][j] == 'O')
ans ++;
}
printf("Case %d: %s\n", ++cas, ANS[ans % 2]);
}
return 0;
}

然后就看到K题搜索题,思路很明确。广搜每次2个草的结点入队,然后枚举。。现场因为一个下标错了WA了次。。也是唯一一次WA。
K题:

#include <stdio.h>
#include <string.h>
#include <queue>
using namespace std;
#define min(a,b) (a)<(b)?(a):(b)
#define max(a,b) (a)>(b)?(a):(b)
#define INF 0x3f3f3f3f
const int N = 15;
const int d[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};

int t, n, m, res

, num, vis

;
char map

;

struct Node {
int x, y;
} q, p;

void init() {
num = 0;
scanf("%d%d%*c", &n, &m);
for (int i = 0; i < n; i ++) {
gets(map[i]);
for (int j = 0; j < m; j ++)
if (map[i][j] == '#')
num++;
}
}

int bfs(int x1, int y1, int x2, int y2) {
int ans = 0;
memset(res, INF, sizeof(res));
memset(vis, 0, sizeof(vis));
queue<Node>Q;
res[x1][y1] = 0; res[x2][y2] = 0;
q.x = x1; q.y = y1; Q.push(q); q.x = x2; q.y = y2; Q.push(q);
while (!Q.empty()) {
q = Q.front(); Q.pop();
vis[q.x][q.y] = 0;
ans = max(ans, res[q.x][q.y]);
for (int i = 0; i < 4; i ++) {
p.x = q.x + d[i][0];
p.y = q.y + d[i][1];
if (p.x >= 0 && p.x < n && p.y >= 0 && p.y < m && map[p.x][p.y] == '#') {
if (res[p.x][p.y] > res[q.x][q.y] + 1 && !vis[p.x][p.y]) {
res[p.x][p.y] = res[q.x][q.y] + 1;
vis[p.x][p.y] = 1;
Q.push(p);
}
}
}
}
for (int k = 0; k < n; k ++)
for (int l = 0; l < m; l ++)
if (map[k][l] == '#' && res[k][l] == INF)
return INF;
return ans;
}

void solve() {
int ans = INF;
if (num <= 2) ans = 0;
else {
int x1, y1, x2, y2;
for (int i = 0; i < n * m; i ++) {
x1 = i / m; y1 = i % m; if (map[x1][y1] != '#') continue;
for (int j = i + 1; j < n * m; j ++) {
x2 = j / m; y2 = j % m; if (map[x2][y2] != '#') continue;
int t = bfs(x1, y1, x2, y2);
ans = min(ans, t);
}
}
}
if (ans == INF) printf("-1\n");
else printf("%d\n", ans);
}

int main() {
int cas = 0;
scanf("%d", &t);
while (t--) {
init();
printf("Case %d: ", ++cas);
solve();
}
return 0;
}

4题之后,然后是突然灵光一闪有了I题的解法:判断方法是点有没在其他三点之内。这样一来就很水了
I题:

#include <stdio.h>
#include <string.h>
#include <math.h>
const int N = 35;

struct Point {
int x, y;
} p
;

int t, n;

void init() {
scanf("%d", &n);
for (int i = 0; i < n; i ++)
scanf("%d%d", &p[i].x, &p[i].y);
}

double area(int a, int b, int c) {
return p[a].x * p[b].y + p[c].x * p[a].y + p[b].x * p[c].y - p[c].x * p[b].y - p[a].x * p[c].y - p[b].x * p[a].y;
}

bool OK(int a, int b, int c, int d) {
double sum = fabs(area(a, b, d)) + fabs(area(a, c, d)) + fabs(area(a, b, c));
double save = fabs(area(b, c, d));
if (fabs(sum - save) < 1e-9) return true;
return false;
}

bool judge(int i, int j, int k, int l) {
if (OK(i, j, k, l)) return false;
if (OK(j, i, k, l)) return false;
if (OK(k, j, i, l)) return false;
if (OK(l, j, k, i)) return false;
return true;
}

int solve() {
int ans = 0;
for (int i = 0; i < n; i ++)
for (int j = i + 1; j < n; j ++)
for (int k = j + 1; k < n; k ++)
for (int l = k + 1; l < n; l ++) {
if (judge(i, j, k, l))
ans++;
}
return ans;
}

int main() {
int cas = 0;
scanf("%d", &t);
while (t--) {
init();
printf("Case %d: %d\n", ++cas, solve());

}
return 0;
}

之后就想A题和E题。。A题最终想出了点的构造方式,写起来就很水了。。
A题:

#include <stdio.h>
#include <string.h>
#include <math.h>
const int N = 110;
int t, n;
double x
, y
;

void init() {
x[1] = 0; y[1] = 0;
x[2] = 0; y[2] = 1;
x[3] = sqrt(3) / 2; y[3] = 0.5;
x[4] = sqrt(3) / 2 - 1; y[4] = 0.5;
for (int i = 5; i <= 100; i ++) {
x[i] = x[2] + ((i - 4) * 0.005);
y[i] = sqrt(1 - x[i] * x[i]);
}
}

int main() {
init();
scanf("%d", &t);
while (t--) {
scanf("%d", &n);
if (n < 4) printf("No\n");
else {
printf("Yes\n");
for (int i = 1; i <= n; i ++)
printf("%.6lf %.6lf\n", x[i], y[i]);
}
}
return 0;
}


最后剩1个小时想E题,想到是贪心的区间选点,但是没想到构造区间的方法,是去解二元方程组。。
E题:

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
using namespace std;
const int N = 100005;

struct Point {
double x, y, z;
double xk, yk, zk;
double s, e;
int vis;
} p
;

int t, n, ansn, ansc;
double r;

void init() {
ansn = ansc = 0;
memset(p, 0, sizeof(p));
scanf("%d%lf", &n, &r);
for (int i = 0; i < n; i ++) {
scanf("%lf%lf%lf%lf%lf%lf", &p[i].x, &p[i].y, &p[i].z, &p[i].xk, &p[i].yk, &p[i].zk);
}
}

bool cmp(Point a, Point b) {
return a.e < b.e;
}
void solve() {
ansn = n;
for (int i = 0; i < n; i ++) {
double a = p[i].xk * p[i].xk + p[i].yk * p[i].yk + p[i].zk * p[i].zk;
double b = 2 * p[i].x * p[i].xk + 2 * p[i].y * p[i].yk + 2 * p[i].z * p[i].zk;
double c = p[i].x * p[i].x + p[i].y * p[i].y + p[i].z * p[i].z - r * r;
double dlt =b * b - 4 * a * c;
if (dlt < 0) {
ansn--;
continue;
}
double k1 = (-b + sqrt(dlt)) / (2 * a);
double k2 = (-b - sqrt(dlt)) / (2 * a);
if (k1 < 0 && k2 < 0) {
ansn--;
continue;
}
if (k2 < k1) {
if (k2 < 0) k2 = 0;
p[i].s = k2; p[i].e = k1;
}
else {
if (k1 < 0) k1 = 0;
p[i].s = k1; p[i].e = k2;
}
p[i].vis = 1;
}
sort(p, p + n, cmp);
double c = -1000000000;
for (int ii = 0; ii < n; ii ++) {
if (!p[ii].vis) continue;
if (p[ii].s > c) {
c = p[ii].e;
ansc ++;
}
}
}

int main() {
int cas = 0;
scanf("%d", &t);
while (t--) {
init();
solve();
printf("Case %d: %d %d\n", ++cas, ansn, ansc);
}
return 0;
}

E题后面在FZU上时间改成1秒了。。要用输入外挂才能过了。。。
总结:这次比赛,还是比较稳的,基本1A,不求很快,发挥也还行。。运气也还不错(最后是金奖,虽然是最后一名哈哈哈。),也有点遗憾最后第7题没出。总之结果还是很满意了。。再接再厉
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐