查找、搜索
21. 成语接龙
Description
小张非常喜欢与朋友们玩成语接龙的游戏,但是作为“文化沙漠”的小张,成语的储备量有些不足。现在他的大脑中存储了个成语,成语中的四个汉字都用一个1000000以内的正整数来表示。现在小张的同学为了考验他给出了他一个成语做开头和一个成语做结尾,如果小张能通过成语接龙的方式说到结尾的成语,他就能够成功完成游戏。他想知道最少能说几个成语能够成功完成游戏。
Input
接下来行,每行4个1000000以内的正整数,表示一个成语。
下一行4个1000000以内的正整数,表示开始成语。
下一行4个1000000以内的正整数,表示结束成语。
保证开始成语和结束成语在小张的成语储备之中。
Output
一行一个整数,表示最少说几个成语能够完成游戏。如果无法完成输出-1。
Notes
三个成语分别是(1,2,3,4)(4,5,6,7)(7,8,9,10)
测试输入 | 期待的输出 | 时间限制 | 内存限制 | 额外进程 | |
---|---|---|---|---|---|
测试用例 1 | 以文本方式显示
| 以文本方式显示
| 1秒 | 64M | 0 |
测试用例 2 | 以文本方式显示
| 以文本方式显示
| 1秒 | 64M | 0 |
代码如下:
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#define MAX_SIZE 1000001
typedef struct Node {
int data;
struct Node* next;
} Node;
typedef struct {
int front;
int rear;
int size;
int* array;
} Queue;
void initQueue(Queue* queue, int size) {
queue->front = 0;
queue->rear = -1;
queue->size = size;
queue->array = (int*)malloc(size * sizeof(int));
}
bool isQueueEmpty(Queue* queue) {
return queue->rear < queue->front;
}
void enqueue(Queue* queue, int item) {
queue->array[++queue->rear] = item;
}
int dequeue(Queue* queue) {
return queue->array[queue->front++];
}
Node* createNode(int data) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->data = data;
newNode->next = NULL;
return newNode;
}
void addEdge(Node** graph, int start, int end) {
Node* newNode = createNode(end);
newNode->next = graph[start];
graph[start] = newNode;
}
int main() {
int m;
scanf("%d", &m);
int s1, s2, s3, s4, e1, e2, e3, e4;
bool* visited = (bool*)malloc(MAX_SIZE * sizeof(bool));
for (int i = 0; i < MAX_SIZE; i++) {
visited[i] = false;
}
int* step = (int*)malloc(MAX_SIZE * sizeof(int));
for (int i = 0; i < MAX_SIZE; i++) {
step[i] = -1;
}
Queue que;
initQueue(&que, MAX_SIZE);
Node** graph = (Node**)malloc(MAX_SIZE * sizeof(Node*));
for (int i = 0; i < MAX_SIZE; i++) {
graph[i] = NULL;
}
for (int i = 0; i < m; i++) {
int start, end;
scanf("%d %*d %*d %d", &start, &end);
addEdge(graph, start, end);
}
scanf("%d %d %d %d", &s1, &s2, &s3, &s4);
scanf("%d %d %d %d", &e1, &e2, &e3, &e4);
if (s1 == e1 && s2 == e2 && s3 == e3 && s4 == e4) {
printf("1\n");
return 0;
}
else {
enqueue(&que, s4);
visited[s4] = true;
step[s4] = 1;
while (!isQueueEmpty(&que)) {
int cur = dequeue(&que);
for (Node* temp = graph[cur]; temp != NULL; temp=temp->next) {
int next = temp->data;
if (!visited[next]) {
enqueue(&que, next);
visited[next] = true;
step[next] = step[cur] + 1;
if (cur != e1 && next == e4) {
visited[next] = false;
step[next]--;
}
if (cur == e1 && next == e4) {
break;
}
}
}
}
printf("%d\n", step[e4]);
return 0;
}
}
22. 地下城与勇士
代码如下:
#include <stdio.h>
#include <stdbool.h>
#include <limits.h>
#define N 100
#define M 100
#define K 100
struct node {
int x, y, step;
};
int T,front=0,rear=0;
int dir[4][2]={0,1,1,0,-1,0,0,-1};
char map[N][M];
bool visited[N][M][K];
struct node que[N*M*K];
void push(struct node n){
que[rear++]=n;
}
struct node pop(){
return que[front++];
}
bool empty(){
return front==rear;
}
int main(){
scanf("%d",&T);
while (T--){
int n,m,k,Sx,Sy,i,j,ans;
scanf("%d%d%d",&n,&m,&k);
front=rear=0;
for(i=0;i<n;i++){
scanf("%s", map[i]);
for(j=0;j<m;j++){
if(map[i][j]=='S'){
Sx=i;
Sy=j;
}
for (int l = 0; l < k; l++) visited[i][j][l]=false;
}
}
ans=INT_MAX;
push((struct node) {Sx,Sy,0});
visited[Sx][Sy][0]=true;
while(!empty()){
struct node tmp=pop();
if(map[tmp.x][tmp.y]=='E'){
ans = tmp.step;
break;
}
for(i=0;i<4;i++){
int x=tmp.x+dir[i][0],y=tmp.y+dir[i][1],stp=tmp.step+1;
if(x<0||x>n-1 ||y<0||y>m-1||map[x][y]=='#'||visited[x][y][stp % k]) continue;
if(map[x][y]=='*'&& (stp % k)) continue;
push((struct node){x,y,stp});
visited[x][y][stp%k]=true;
}
}
if(ans==INT_MAX) printf("-1\n");
else printf("%d\n",ans);
}
}
23. 带旋转的数独游戏
代码如下:
#include <stdio.h>
#include <string.h>
#include <limits.h>
#define N 30
int a[N][N];
int ck1[N][N + 1];
int ck2[N][N + 1];
struct Node
{
int x, y, t;
};
int ans;
struct Node as[N * N], fas[N * N];
int asSize = 0, fasSize = 0;
int get(char ch)
{
if (ch == '0')
return 10;
else if (ch > '0' && ch <= '9')
return ch - '0';
else
return ch - 'A' + 11;
}
void roat(int x, int y)
{
int xx = (x)*4;
int yy = (y)*4;
int g[5][5];
for (int i = xx; i <= xx + 3; i++)
{
for (int j = yy; j <= yy + 3; j++)
{
g[i - xx][j - yy] = a[i][j];
}
}
for (int i = xx; i <= xx + 3; i++)
{
for (int j = yy; j <= yy + 3; j++)
{
a[i][j] = g[j - yy][3 + xx - i];
}
}
}
int check(int aa, int bb)
{
aa = aa * 4;
bb = bb * 4;
for (int i = aa; i <= aa + 3; i++)
for (int j = bb; j <= bb + 3; j++)
{
int num = a[i][j];
if (ck1[i][num] || ck2[j][num])
{
return 0;
}
}
for (int i = aa; i <= aa + 3; i++)
for (int j = bb; j <= bb + 3; j++)
{
int num = a[i][j];
ck1[i][num] = 1, ck2[j][num] = 1;
}
return 1;
}
void uncheck(int aa, int bb)
{
aa = aa * 4;
bb = bb * 4;
for (int i = aa; i <= aa + 3; i++)
for (int j = bb; j <= bb + 3; j++)
{
int num = a[i][j];
ck1[i][num] = 0, ck2[j][num] = 0;
}
}
void dfs(int x, int y, int t)
{
if (x == 4)
{
if (t < ans)
{
ans = t;
memcpy(fas, as, sizeof(struct Node) * asSize);
fasSize = asSize;
}
return;
}
for (int i = 0; i < 4; i++)
{
if (!check(x, y))
{
roat(x, y);
continue;
}
as[asSize++] = (struct Node){x + 1, y + 1, i};
if (y == 3)
{
dfs(x + 1, 0, t + i);
}
else
dfs(x, y + 1, t + i);
asSize--;
uncheck(x, y);
roat(x, y);
}
}
int main()
{
int T, i, j, k;
scanf("%d", &T);
while (T--)
{
ans = INT_MAX;
asSize = 0;
fasSize = 0;
memset(ck1, 0, sizeof ck1);
memset(ck2, 0, sizeof ck2);
for (i = 0; i < 16; i++)
for (j = 0; j < 16; j++)
{
char x;
scanf(" %c", &x);
int gx = get(x);
a[i][j] = gx;
}
dfs(0, 0, 0);
printf("%d\n", ans);
for (i = 0; i < fasSize; i++)
{
struct Node per = fas[i];
for (j = 0; j < per.t; j++)
{
printf("%d %d\n", per.x, per.y);
}
}
}
return 0;
}
24.绳子切割
Description
有N条绳子,它们的长度分别为Li,Li都是正整数。如果从它们中切割出K条长度相同的绳子(绳子的长度为整数),这K条绳子每条最长能有多长?
Input
Output
一行一个大于等于0的整数,表示条绳子中每条绳子的最大长度,注意:如果无法切割则输出0。
测试输入 | 期待的输出 | 时间限制 | 内存限制 | 额外进程 | |
---|---|---|---|---|---|
测试用例 1 | 以文本方式显示
| 以文本方式显示
| 1秒 | 64M | 0 |
测试用例 3 | 以文本方式显示
| 以文本方式显示
| 1秒 | 64M | 0 |
代码如下:
#include <stdio.h>
#include <stdlib.h>
int compare(const void *a, const void *b){
return (*(int *)b - *(int *)a);
}
int check(int mid, int *L, int N, int K){
int count = 0;
for (int i = 0; i < N; i++) count += L[i] / mid;
return count >= K;
}
int binary_search(int l, int r, int *L, int N, int K){
int ans = 0;
while (l <= r){
int mid = l + (r - l) / 2;
if (check(mid, L, N, K)){
ans = mid;
l = mid + 1;
}
else r = mid - 1;
}
return ans;
}
int main()
{
int N, K, i,r,l,ans;
scanf("%d", &N);
int *L = (int *)calloc(N, sizeof(int));
long long sum = 0;
for (i = 0; i < N; i++)
{
scanf("%d", &L[i]);
sum += L[i];
}
qsort(L, N, sizeof(int), compare);
scanf("%d", &K);
l = 1, r = sum / K;
ans = binary_search(l, r, L, N, K);
printf("%d\n", ans);
return 0;
}
25. 进圈
代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct node
{
int x, y;
int step;
} N;
typedef struct queue
{
N *data;
int front;
int rear;
int size;
} Q;
N dequeue(Q *q)
{
N item = q->data[q->front];
q->front = (q->front + 1) % q->size;
return item;
}
void CSH(Q *q, int n)
{
q->data = (N *)malloc(n * sizeof(N));
q->front = 0;
q->rear = 0;
q->size = n;
}
void ENQ(Q *q, N item)
{
q->data[q->rear] = item;
q->rear = (q->rear + 1) % q->size;
}
int is_empty(Q *q)
{
return q->front == q->rear;
}
const int dir_x[4] = {0, 0, 1, -1};
const int dir_y[4] = {1, -1, 0, 0};
int main()
{
int n, m, k, i, j, ans, x, y, x1, y1, x2, y2;
scanf("%d%d%d", &n, &m, &k);
char map[n][m];
for (i = 0; i < n; ++i) scanf("%s", map[i]);
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
Q que;
CSH(&que, n * m);
N start = {x1 - 1, y1 - 1, 0};
ENQ(&que, start);
int visited[n][m];
memset(visited, 0, sizeof(visited));
ans = -1;
while (!is_empty(&que))
{
N tmp = dequeue(&que);
for (i = 0; i < 4; ++i)
{
for (j = 1; j < k + 1; j++)
{
x = tmp.x + dir_x[i] * j;
y = tmp.y + dir_y[i] * j;
if (x < 0 || x >= n || y < 0 || y >= m || map[x][y] == '#') break;
if (visited[x][y] == 1) continue;
if (x == x2 - 1 && y == y2 - 1)
{
ans = tmp.step + 1;
printf("%d\n", ans);
return 0;
}
N next = {x, y, tmp.step + 1};
ENQ(&que, next);
visited[x][y] = 1;
}
}
}
printf("%d\n", ans);
return 0;
}