题目传送:“玲珑杯”第七届郑州轻工业学院ACM程序设计大赛——正式赛
先给出我自己看了的题的题解吧
A - 彩票
水题
AC代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int main() {
int T, N;
scanf("%d", &T);
while(T--) {
scanf("%d", &N);
if(!(N & 1) && N >= 4) {
printf("Yes\n");
}
else printf("No\n");
}
return 0;
}
C - 数列游戏
比较坑的一个题,一直都是Alice赢,一开始我还以为博弈论,不太会,就没看,然后一看榜,好多人过啦,肯定有猫腻,然后大胆的试了一下过啦
AC代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
using namespace std;
int main() {
int T;
LL N;
scanf("%d", &T);
while(T--) {
cin >> N;
printf("Alice\n");
}
return 0;
}
E - 汇编语言
其实就是个简单的模拟题,只要好好敲都可以做出来,当时,我们都分开做题了,一直调试,浪费好多时间,大概是实力还不够吧,要是代码能力还好一点,我估计早就A掉了
现在我还是在一直YY我大一要是就开始学算法了该有多好
思路:就是模拟过去就好了
AC代码:
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#include <cctype>
#define LL long long
using namespace std;
int T, N;
LL AX, AH, AL;
LL BX, BH, BL;
LL CX, CH, CL;
LL DX, DH, DL;
char op[10], s[35];
char s1[35], s2[35];
void up_down() {
AH = AX / 256; AL = AX % 256;
BH = BX / 256; BL = BX % 256;
CH = CX / 256; CL = CX % 256;
DH = DX / 256; DL = DX % 256;
}
void down_up() {
AX = AH * 256 + AL;
BX = BH * 256 + BL;
CX = CH * 256 + CL;
DX = DH * 256 + DL;
}
LL *judge(char *s) {
if(strcmp(s, "AX") == 0) return &AX;
else if(strcmp(s, "AH") == 0) return &AH;
else if(strcmp(s, "AL") == 0) return &AL;
else if(strcmp(s, "BX") == 0) return &BX;
else if(strcmp(s, "BH") == 0) return &BH;
else if(strcmp(s, "BL") == 0) return &BL;
else if(strcmp(s, "CX") == 0) return &CX;
else if(strcmp(s, "CH") == 0) return &CH;
else if(strcmp(s, "CL") == 0) return &CL;
else if(strcmp(s, "DX") == 0) return &DX;
else if(strcmp(s, "DH") == 0) return &DH;
else if(strcmp(s, "DL") == 0) return &DL;
}
LL b_d(char *s) {
int len = strlen(s);
LL ret = 0;
for(int i = 0; i < len - 1; i++) {
ret *= 2;
if(s[i] == '1') ret += 1;
}
return ret;
}
LL d_d(char *s) {
int len = strlen(s);
LL ret = 0;
for(int i = 0; i < len; i++) {
ret = ret * 10 + s[i] - '0';
}
return ret;
}
LL h_d(char *s) {
int len = strlen(s);
LL ret = 0;
for(int i = 1; i < len - 1; i++) {
ret *= 16;
if(s[i] <= '9' && s[i] >= '0') ret += s[i] - '0';
else ret += (s[i] - 'A' + 10);
}
return ret;
}
int main() {
/*char a[123] = "123004";
printf("%d\n", d_d(a));*/
scanf("%d", &T);
while(T --) {
scanf("%d", &N);
AX = AH = AL = 0;
BX = BH = BL = 0;
CX = CH = CL = 0;
DX = DH = DL = 0;
for(int i = 0; i < N; i++) {
scanf("%s", op);
if(strcmp(op, "MOV") == 0) {
scanf("%s", s);
s[2] = '\0';
strcpy(s1, s);
strcpy(s2, s + 3);
//printf("%s %s\n", s1, s2);
//system("pause");
LL *p = judge(s1);
int len = strlen(s2);
if((s2[0] <= '9' && s2[0] >= '0') || s2[len - 1] == 'B' || s2[len - 1] == 'H') {
int t;
if(s2[len - 1] == 'B') {
t = b_d(s2);
}
else if(s2[len - 1] == 'H') {
t = h_d(s2);
}
else t = d_d(s2);
*p = t;
if(s1[1] == 'X') up_down();
else down_up();
}
else {
LL *q = judge(s2);
*p = *q;
if(s1[1] == 'X') up_down();
else down_up();
}
}
else if(strcmp(op, "ADD") == 0) {
scanf("%s", s);
s[2] = '\0';
strcpy(s1, s);
strcpy(s2, s + 3);
LL *p = judge(s1);
if(s2[0] <= '9' && s2[0] >= '0') {
int t;
int len = strlen(s2);
if(s2[len - 1] == 'B') {
t = b_d(s2);
}
else if(s2[len - 1] == 'H') {
t = h_d(s2);
}
else t = d_d(s2);
*p += t;
if(s1[1] == 'X') up_down();
else down_up();
}
else {
LL *q = judge(s2);
*p += *q;
if(s1[1] == 'X') up_down();
else down_up();
}
}
else {
scanf("%s", s);
LL *p = judge(s);
if(s[1] == 'X') {
DX = (*p * AX) / 65536;
AX = (*p * AX) % 65536;
//printf("%d %d\n", AX, DX);
up_down();
}
else {
AX = *p * AL;
//printf("%d\n", AX);
up_down();
}
}
}
cout << AX << " " << BX << " " << CX << " " << DX << endl;
}
return 0;
}
G - 矩阵(2015/5/17补)
思路:今天又巩固了下树状数组,然后想起这题,顺便做做,刚看题感觉是二维树状数组(记得zy说是的),啪啪啪几下搞了下,超时了,心想树状数组都超时了,那用啥高级的算法好,然后仔细看了下题,居然修改最多十次,真醉了,做法很简单,只要记录下当前的修改过的,然后在输出ans的时候判断修改过的是否包含在该矩阵内即可,预处理是n^2的,然后查询是O(1)的,估计这题就卡到查询上了,因为树状数组查询是O(logn)的,预处理是O(n*logn)的,更新是O(logn)的
AC代码:
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <deque>
#include <cctype>
#define LL long long
#define INF 0x7fffffff
using namespace std;
int n, m, q;
int a[1005][1005];
int sum[1005][1005];
int mo[150];
int x[150];
int y[150];
void init(int n, int m) {
for(int i = 1; i <= n; i ++) {
for(int j = 1; j <= m; j ++) {
a[i][j] = i + j;
sum[i][j] = a[i][j] + sum[i-1][j] + sum[i][j-1] - sum[i-1][j-1];
}
}
}
int main() {
int T;
scanf("%d", &T);
while(T --) {
scanf("%d %d %d", &n, &m, &q);
init(n, m);
int cnt = 0;
for(int i = 0; i < q; i ++) {
char op[5];
scanf("%s", op);
if(op[0] == 'Q') {
int a, b, c, d;
scanf("%d %d %d %d", &a, &b, &c, &d);
int ans = sum[c][d] - sum[a - 1][d] - sum[c][b - 1] + sum[a - 1][b - 1];
for(int i = 0; i < cnt; i ++) {
if(x[i] <= c && x[i] >= a && y[i] <= d && y[i] >= b) {
ans += mo[i];
}
}
printf("%d\n", ans);
}
else {
int t;
scanf("%d %d %d", &x[cnt], &y[cnt], &t);
mo[cnt] = t - a[x[cnt]][y[cnt]];
a[x[cnt]][y[cnt]] = t;
cnt ++;
}
}
}
return 0;
}
I - 旋转图像
水题,就是把矩阵按要求旋转
AC代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int T, N, M;
int mp[55][55];
int ans[55][55];
char s[55];
void print(int a[][55]) {
for(int i = 1; i <= N; i++, printf("\n")) {
for(int j = 1; j <= M; j++) {
printf("%d", a[i][j]);
}
}
}
int main() {
scanf("%d", &T);
while(T--) {
scanf("%d %d", &N, &M);
for(int i = 1; i <= N; i++) {
scanf("%s", s);
int len = strlen(s);
for(int j = 0; j < len; j++) {
if(s[j] == '0') mp[i][j + 1] = 0;
else mp[i][j + 1] = 1;
}
}
int ang;
scanf("%d", &ang);
if(ang == 0) {
print(mp);
}
else if(ang == 90) {
for(int i = 1; i <= N; i++) {
for(int j = 1; j <= M; j++) {
ans[j][N-i+1] = mp[i][j];
}
}
swap(N, M);
print(ans);
}
else if(ang == 180) {
for(int i = 1; i <= N; i++) {
for(int j = 1; j <= M; j++) {
ans[N-i+1][M-j+1] = mp[i][j];
}
}
print(ans);
}
else if(ang == 270) {
for(int i = 1; i <= N; i++) {
for(int j = 1; j <= M; j++) {
ans[M-j+1][i] = mp[i][j];
}
}
swap(N, M);
print(ans);
}
}
return 0;
}
J - 堆
判断是不是最小堆,这个题当时没仔细看,让ZY和SH去搞了,然后我自己一个人慢慢搞模拟题,其实当时我再看一眼会好点,一起搞有时候虽然浪费时间,但是会比一直不过题好点
思路是简单的DFS
AC代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int T, N;
int mp[105][105];
int v[105];
int vis[105];
int flag;
void dfs(int x, int cur) {
if(flag) return;
for(int i = 1; i <= N; i++) {
if(!vis[i] && mp[x][i]) {
vis[i] = 1;
if(v[i] < cur) {
flag = 1;
return;
}
else {
dfs(i, v[i]);
}
}
}
}
int main() {
scanf("%d", &T);
while(T--) {
scanf("%d", &N);
for(int i = 1; i <= N; i++) {
scanf("%d", &v[i]);
}
memset(mp, 0, sizeof(mp));
for(int i = 1; i < N; i++) {
int u, v;
scanf("%d %d", &u, &v);
mp[u][v] = 1;
mp[v][u] = 1;
}
if(N == 1) {
printf("Yes\n");
continue;
}
flag = 0;
memset(vis, 0, sizeof(vis));
vis[1] = 1;
dfs(1, v[1]);
if(flag) {
printf("No\n");
}
else printf("Yes\n");
}
return 0;
}
总结一下:实力还很弱,还需要努力
比赛的时候,我们照原样分开看题,然后我先去水的第一题,wa了一下,当时就慌了一下,看错了题,可能就是这时候开始了这比赛的失败吧,然后接着的两题都很顺利的A掉了,但是此时也有些题有人过啦,这之后我们陷进了无尽的调试过程,我觉得好难受,代码能力啊,之后的几个小时里我都在搞模拟题,应该是说被那个五子棋坑了,坑了好久,,,哎,,实力还是好弱,,最后看的那个汇编语言的题,觉得很简单,就是实现起来有点复杂,但是当时已经不是最佳状态了,敲错一个字母导致我开始放弃了,,,然后就没有然后了,,,,
每次的失败都让我保持着很清醒的认知:只学了才几个月算法的我还有很长的路要走