分享一下华子8月31号机考代码
仅供参考
第一题基本的字符串操作,用二维数组存放句子和单词表里的单词,注意大小写不敏感,最后遍历搜索即可;
第二题深度优先搜索算法,注意回溯的时候炸弹炸掉的墙要复原。且炸弹和陷阱只可以使用一次。
第三题动态规划,注意dp数组的含义,我设的dp[i][j]数组包含了在第i个充电桩充电和等待的时间,以及到达下一个充电桩的路途中所使用的时间。然后倒叙遍历。正序遍历应可以,不过dp数组的含义会不一样。注意边界初始化条件即可。
第一题:
#include<stdio.h> #include<string.h> int main(void) { char str[10005]={0}; char sentence[250][60]={0}; char backupsentence[250][60]={0}; scanf("%[^\n]", &str); getchar(); char word[2100][60] = { 0 }; char str2[100001] = { 0 }; scanf("%[^\n]", &str2); int len1 = strlen(str); int j1 = 0; int j2 = 0; int jj1 = 0; int jj2 = 0; for (int i = 0; i < len1; i++) { if((str[i]>='a'&&str[i]<='z')||(str[i]>='A'&&str[i]<='Z')) { while (!(str[i] == ' ' || str[i] == ',' || str[i] == '.') || str[i] == '"') { sentence[j1][j2++] = str[i]; backupsentence[jj1][jj2++] = str[i]; i++; } i--; for (int m = 0; m < j2; m++) { if (sentence[j1][m] >= 'A' && sentence[j1][m] <= 'Z') { sentence[j1][m] += 32; } } j1++; j2 = 0; jj1++; jj2 = 0; } if (str[i] == ' '|| str[i] == ',' || str[i] == '.') { sentence[j1][j2++] = str[i]; backupsentence[jj1][jj2++] = str[i]; j1++; j2 = 0; jj1++; jj2 = 0; } if (str[i] == '"') { sentence[j1][j2++] = str[i]; backupsentence[jj1][jj2++] = str[i]; i++; while (str[i] != '"') { sentence[j1][j2++] = str[i]; backupsentence[jj1][jj2++] = str[i]; i++; } for (int m = 1; m < j2; m++) { if (sentence[j1][m] >= 'A' && sentence[j1][m] <= 'Z') { sentence[j1][m] += 32; } } sentence[j1][j2++] = str[i]; backupsentence[jj1][jj2++] = str[i]; j1++; j2 = 0; jj1++; jj2 = 0; } }//sentence输入完毕 int list = j1;//包含标点符号,sentence中单词的数量 /*for (int i = 0; i < list; i++) { printf("%s\n",backupsentence[i]); }*/ int len2 = strlen(str2); int k1 = 0; int k2 = 0; for (int i = 0; i < len2; i++) { if ((str2[i] >= 'a' && str2[i] <= 'z') || (str2[i] >= 'A' && str2[i] <= 'Z')) { while (str2[i] != ' ') { word[k1][k2++] = str2[i]; i++; } i--; for (int m = 0; m < k2; m++) { if (word[k1][m] >= 'A' && word[k1][m] <= 'Z') { word[k1][m] += 32; } } k1++; k2 = 0; } if (str2[i] == ' ') { //word[k1][k2++] = str2[i]; //k1++; k2 = 0; } } int index = k1; /*for (int i = 0; i < index; i++) { printf("%s\n", word[i]); }*/ //printf("%d", list); //printf("%d\n", index); int replace[250] = { 0 }; int num[250] = { 0 }; for (int i = 0; i < list; i++) { int maxindex = 0; if (strcmp(sentence[i], " ") != 0 && strcmp(sentence[i], ",") != 0 && strcmp(sentence[i], ".") != 0) { for (int m = 0; m < index; m++) { if (strcmp(sentence[i], word[m]) == 0) { replace[i] = 1; maxindex = (maxindex > m) ? maxindex : m; } num[i] = maxindex; } } } for (int i = 0; i < list; i++) { if (replace[i] == 0) { printf("%s", backupsentence[i]); } else if (replace[i] == 1) { printf("%d", num[i]); } } return 0; }第二题:
#include<stdio.h> #include<string.h> int n, m; int map[30][30] = { 0 }; int startx, starty; int endx, endy; int mintime = 999; //int time=0; int vis[30][30] = { 0 }; int dx[4] = { 0,1,0,-1 }; int dy[4] = { 1,0,-1,0 }; void dfs(int x, int y, int time) { int tx, ty; if (x == endx && y == endy) { mintime = (mintime > time) ? time : mintime; return; } for (int k = 0; k < 4; k++) { tx = x + dx[k]; ty = y + dy[k]; if (tx >= 0 && tx < n && ty >= 0 && ty < m && vis[tx][ty] == 0) { if (map[tx][ty] == 0||map[tx][ty]==3||map[tx][ty]==2) { vis[tx][ty] = 1; dfs(tx, ty, time + 1); vis[tx][ty] = 0; } else if (map[tx][ty] == 4) { map[tx][ty] = 0;//陷阱只可以发挥一次作用 vis[tx][ty] = 1; dfs(tx, ty, time + 3); vis[tx][ty] = 0; map[tx][ty] = 4;//陷阱复原 } else if (map[tx][ty] == 6) { map[tx][ty] = 0;//炸弹只可以发挥一次作用 vis[tx][ty] = 1; int memx[10] = { 0 }; int memy[10] = { 0 }; int j1 = 0; for (int m = 0; m < 4; m++) { if (map[tx + dx[m]][ty + dy[m]] == 1) { memx[j1++] = tx + dx[m]; memy[j1++] = ty + dy[m]; map[tx + dx[m]][ty + dy[m]] = 0; } } dfs(tx, ty, time + 1); map[tx][ty] = 6;//炸弹复原 for (int m = 0; m < j1; m++) { map[memx[m]][memy[m]] = 1;//炸毁的墙复原 } } } } return; } int main(void) { scanf("%d%d", &n, &m); for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { scanf("%d", &map[i][j]); if (map[i][j] == 2) { startx = i; starty = j; } if (map[i][j] == 3) { endx = i; endy = j; } } }//输入完毕 /*startx = 0; starty = 0; endx = n - 1; endy = m - 1;*/ vis[startx][starty] = 1; dfs(startx, starty, 0); //printf("%d %d\n", startx,starty); //printf("%d %d\n", endx, endy); printf("%d", mintime); return 0; }
第三题:
#include<stdio.h> #include<string.h> //二维dp数组解法 int D; int N; typedef struct { int distance; int time; }STOP; int dp[10005][1010] = { 0 }; int dis = 0; int main(void) { scanf("%d%d", &D, &N); STOP stop[10005]={0}; for (int i = 1; i<=N; i++) { scanf("%d%d", &stop[i].distance, &stop[i].time); }//输入完毕 stop[N + 1].distance = D; stop[N + 1].time = 0; //printf("%d %d", stop[0].distance, stop[0].time); //两个特殊情况,限制两个站点之间距离小于1000 for (int i = 0; i < N; i++) { if (stop[i + 1].distance - stop[i].distance > 1000) { printf("-1"); return 0; } } if (D - stop[N].distance > 1000) { printf("-1"); return 0; } //int dp[i][j]表示在到达第i个站点,剩余续航公里数j,到达下一个站点前花掉的时间 /*if(stop[i+1].distance-stop[i].distance>j),dis=stop[i+1].distance-stop[i].distance; * 此时在第i个站点必须充电,dp[i][j]=dp[i+1][1000-dis]+dis/100+stop[i].time+1; * if(dis<=j)可以选择充电或者不充,如果充电则dp[i][j]=dp[i+1][1000-dis]+dis/100+stop[i].time+1; * 如果选择不充电,则dp[i][j]=dp[i+1][j-dis]+dis/100; //*/ //初始化dp for (int i = 0; i <= 1000; i += 100) { int temp = 0;temp = D - stop[N].distance; if(i>temp){ dp[N][i] = temp / 100; } else { dp[N][i] = temp / 100 + stop[N].time + 1; } } //动态规划 for (int i = N-1; i > 0; i--) { dis = stop[i + 1].distance - stop[i].distance; for (int j = 0; j <= 1000; j += 100) { if(j<dis) { dp[i][j] = dp[i + 1][1000 - dis] + dis / 100 + stop[i].time + 1; } if (j >= dis) { int temp1; temp1= dp[i + 1][1000 - dis] + dis / 100 + stop[i].time + 1; int temp2; temp2 = dp[i + 1][j - dis] + dis / 100; dp[i][j] = (temp1 > temp2) ? temp2 : temp1; } } } printf("%d",dp[1][1000-stop[1].distance]+stop[1].distance/100); return 0; }