山东大学计算机科学与技术学院程序设计思维与实践作业week3-搜索

山东大学计算机科学与技术学院程序设计思维与实践作业3
山大程序设计思维与实践作业
sdu程序设计思维与实践
山东大学程序设计思维实践作业H3
山大程序设计思维实践作业H3
山东大学程序设计思维与实践
程序设计思维实践作业H3
山东大学计算机科学与技术学院程序设计思维与实践作业
week3-搜索
相关资料:GitHub

A : 游戏

问题描述
  有 n 个小朋友围成一圈玩游戏,小朋友从 1 至 n 编号,2 号小朋友坐在 1 号小朋友的顺时针方向,3 号小朋友坐在 2 号小朋友的顺时针方向,……,1 号小朋友坐在 n 号小朋友的顺时针方向。
  游戏开始,从 1 号小朋友开始顺时针报数,接下来每个小朋友的报数是上一个小朋友报的数加 1。若一个小朋友报的数为 k 的倍数或其末位数(即数的个位)为 k,则该小朋友被淘汰出局,不再参加以后的报数。当游戏中只剩下一个小朋友时,该小朋友获胜。
  例如,当 n=5, k=2 时:
  1 号小朋友报数 1;
  2 号小朋友报数 2 淘汰;
  3 号小朋友报数 3;
  4 号小朋友报数 4 淘汰;
  5 号小朋友报数 5;
  1 号小朋友报数 6 淘汰;
  3 号小朋友报数 7;
  5 号小朋友报数 8 淘汰;
  3 号小朋友获胜。

给定 n 和 k,请问最后获胜的小朋友编号为多少?

输入格式
输入一行,包括两个整数 n 和 k,意义如题目所述。

输出格式
输出一行,包含一个整数,表示获胜的小朋友编号。

样例 1
输入
5 2
输出
3
样例 2
输入
7 3
输出
4
数据规模和约定
对于所有评测用例,1 ≤ n ≤ 1000,1 ≤ k ≤ 9

#include<bits/stdc++.h>
using namespace std;
int main() {
    int number=1,a=0,x=0,i=0;
    cin>>a>>x;
    queue<int, deque<int> > q;
    for(i=1;i<=a;i++) {
        q.push(i);
    }
    while(q.size()>1) { 
        int top = q.front(); 
        q.pop();    
        if(number%x!=0 && number%10!=x) { 
            q.push(top);   
        }
        number++;  
    }
    cout<<q.front(); 
    return 0;
}

B : 跳一跳

问题描述
 近来,跳一跳这款小游戏风靡全国,受到不少玩家的喜爱。
  简化后的跳一跳规则如下:玩家每次从当前方块跳到下一个方块,如果没有跳到下一个方块上则游戏结束。
  如果跳到了方块上,但没有跳到方块的中心则获得 1 分;跳到方块中心时,若上一次的得分为 1 分或这是本局游戏的第一次跳跃则此次得分为 2 分,否则此次得分比上一次得分多两分(即连续跳到方块中心时,总得分将 +2,+4,+6,+8…)。
  现在给出一个人跳一跳的全过程,请你求出他本局游戏的得分(按照题目描述的规则)。

输入格式
输入包含多个数字,用空格分隔,每个数字都是 1,2,0 之一,1 表示此次跳跃跳到了方块上但是没有跳到中心,2 表示此次跳跃跳到了方块上并且跳到了方块中心,0 表示此次跳跃没有跳到方块上(此时游戏结束)。

输出格式
输出一个整数,为本局游戏的得分(在本题的规则下)。

样例输入
1 1 2 2 2 1 1 2 2 0
样例输出
22
数据规模和约定
对于所有评测用例,输入的数字不超过 30 个,保证 0 正好出现一次且为最后一个数字。

#include<bits/stdc++.h>
using namespace std;
int main(){
    int panduan,sum=0,end=0,f=1;
    while (cin>>panduan && panduan){
        if(panduan==1) {
            sum++;
            end=1;
        }
        else if(panduan==2)
        {
            if(f)
            {
                f=0;
                end=2;
                sum+=2;
            }
            else if(end==1) {
                end=2;
                sum+=end;
            }else{
                    end+=2;
                    sum+=end;
                }
            }
        }
    cout<<sum;
}

C : 奇怪的电梯

问题描述
小 H 有一个奇怪的电梯,电梯可以根据需要停在每个楼层,每个楼层上都对应一个数字Ki(0 <= Ki <= N),该电梯只有两个按钮:“UP"和"DOWN”。在第 i 层楼,如果按下"UP"按钮,电梯将移动到i+Ki层;如果按下"DOWN",电梯将移动到i−Ki层。当然,电梯有一个移动的范围,不能高于 N 且不能低于 1。例如,有一个 5 层楼的建筑物,k1=3,k2=3,k3=1,k4=2,k5=5。从一楼开始,按"UP"按钮,将上升到四楼,如果按"DOWN"按钮,电梯将无法移动,因为它不能下降到-2 楼。
现在问题来了:小 H 想从 A 层移动到 B 层,他至少要按几次"UP"或"DOWN"按钮,你能帮帮他嘛?

输入格式
输入包含多个测试用例。每个测试用例包含两行。
第一行包含上述三个整数 N,A,B(1 <= N,A,B <= 200),第二行包含 N 个整数k1,k2,…kn。
若读取到单个 0,则表示输入结束

输出格式
对于每个测试用例,输出一个整数表示最少按下"UP"或"DOWN"按钮的次数,若无法到达 B 层,请输出"-1"。每个测试用例的输出占一行。

样例输入
5 1 5
3 3 1 2 5
0

样例输出
3
数据规模和约定
1<=N,A,B<=200,0<=ki<=N

提示
隐式图问题

#include<bits/stdc++.h>
using namespace std;
int n=1;
int bfs(int x,int y,int arr[],int panduan[]){
	queue<int> que;
	que.push(x);
	while(!que.empty()){
		
		int now=que.front();
		if(now==y){
			return panduan[now];
		}
		que.pop();
		int top=now+arr[now];
		int bottom=now-arr[now];
		if(top>0&&top<n+1&&panduan[top]==0){
			panduan[top]=panduan[now]+1;
			que.push(top);
		}
		if(bottom>0&&bottom<n+1&&panduan[bottom]==0){
			panduan[bottom]=panduan[now]+1;

			que.push(bottom);
		}
		
	}
	return 0;
}
int main(){	

	int x;
	int y;
	
	while(1){
	
	cin>>n;
	if(n==0){
		break;
	}
	cin>>x>>y;
	int arr[n+1];
	int panduan[n+1]={0};
	panduan[x]=1;
	for(int i=1;i<n+1;i++){
		int temp;
		cin>>temp;
		arr[i]=temp;
	}

	
	int z=bfs(x,y,arr,panduan);
	if(z==0){
		cout<<-1<<endl;
	}
	else{
		cout<<z-1<<endl;
	}
	
	}
}

D : 选数

问题描述
已知 n 个整数 x1,x2,…,xn 和 1 个整数 k(k<n)。从 n 个整数中任选 k 个整数相加,可分别得到一系列的和。例如当n=4,k=3,x1=3,x2=7,x3=12,x4=19时,可得全部的组合与它们的和为:
3+7+12=22 3+7+19=29 7+12+19=38
3+12+19=34
现在,要求你计算出和为素数共有多少种。
例如上例,只有一种的和为素数:3+7+19=29。

输入格式
输入包含两行
第一行两个数 n,k
第二行 n 个数依次表示xi

输出格式
一个整数,表示合法的组合数

样例输入
4 3
3 7 12 19

样例输出
1

数据规模和约定
1<=k<n<=20
1<=xi<=5000000

提示
素数的判定方法
bool prime(int n)
{
if(n1) return false;
if (n
2) return true;
for(int i=2;i*i<=n;i++)
if (n%i==0) return false;
return true;
}

#include <bits/stdc++.h>
using namespace std;

int k,N,a[10000],countt = 0;
bool prime(int N)
{
        if(N==1) return false;
        if(N==2) return true;
	for(int i=2;i*i<=N;i++)
	   if (N%i==0) return false;
	return true; 
}

void dfs(int summ,int mm,int y)
{
    if(prime(summ)&&mm==k)
    {
        countt++;
        return;
    }
    if(mm>k||y>N)return;
    dfs(summ,mm,y+1);
    dfs(summ+a[y],mm+1,y+1);
}


int main()
{
    cin>>N>>k;
    for(int i=1; i<=N; i++)
    cin>>a[i];
    dfs(0,0,1);
    cout<<countt<<endl;
    return 0;
}

E : 棋盘问题

问题描述
小 H 收集到一些形状特殊的棋盘,她想在棋盘上面摆放棋子(棋子都是相同的)。她希望摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,你能帮她求解对于给定形状和大小的棋盘,摆放 k 个棋子的所有可行的摆放方案数 C 嘛?

输入格式
输入含有多组测试数据。
每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个 n*n 的矩阵内描述棋盘,以及摆放棋子的数目。
当为-1 -1 时表示输入结束。
随后的 n 行描述了棋盘的形状:每行有 n 个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。
注意只有#棋盘区域可以摆放棋子。

输出格式
对于每一组数据,给出一行输出,输出摆放的方案数目 C (数据保证 C<2^31)

样例输入
2 1
#.
.#
4 4
…#
…#.
.#…
#…
-1 -1
样例输出
2
1
数据规模和约定
1<=k<=n<=8

#include <iostream>
using namespace std;

class qipan{
public:
    int n,x,countt;
    char r[9][9];
    int s[9] = {0};
    qipan(int a,int b):n(a),x(b){
        countt = 0;
    }
    void dfs(int t,int b){
        if(t > x){
            countt++;
            return;
        }
        for(int i = b;i<=n-(x-t) ;i++){
            for(int j =1;j<=n;j++){
                if(!s[j]&&r[i][j]=='#'){
                    s[j] = 1;
                    dfs(t+1,i+1);
                    s[j] = 0;
                }
            }
        }
    }
};
int main(){
    int a,b;
    while(true){
        cin>>a>>b;
        if (a == -1 && b == -1) break;
            qipan q(a,b);
            for(int i = 0;i<a;i++){
                for(int j = 0;j<a;j++){
                    cin>>q.r[i+1][j+1];
                }

            }
            q.dfs(1,1);
            cout<<q.countt<<endl;
    }
    return 0;
}
  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值