作业比赛编号 : 1280 - 2022年春季学期《算法分析与设计》练习15

又一道简单题

题目描述

输入一个四个数字组成的整数 n,你的任务是数一数有多少种方法,恰好修改一个数字,把它 变成一个完全平方数(不能把首位修改成 0)。比如 n=7844,有两种方法:3844=622 和 7744=882。 

输入

输入第一行为整数 T (1<=T<=1000),即测试数据的组数,以后每行包含一个整数 n (1000<=n<=9999)。 

输出

对于每组数据,输出恰好修改一个数字,把 n变成完全平方数的方案数

样例输入 Copy

2
7844
9121

样例输出 Copy

Case 1: 2
Case 2: 0
#include<algorithm>
#include <math.h>
#include<iostream>
using namespace std;
 bool fun(int x)
{
    int t = sqrt(x);
    if (t * t == x)
    {
        return true;
    }
    else {
        return false;
    }
        
}
 
int main()
{
    int T, n;
    cin >> T;
    for (int i = 1; i <= T; i++)
    {
        cin >> n;
        int count = 0;
        int a = 10, b = 1, temp;
        for (int j = 1; j <= 4; j++)
        {
            int k = (n % a) / b;
            temp = n - k * b;
            for (int c = 0; c <= 9; c++)
            {
                if (!(c == 0 && j == 4) && (c != k))
                    if (fun(temp + c * b))
                        ++count;
            }
            a = a * 10; b = b * 10;
        }
        cout << "Case" << " " << i << ":" << " ";
        cout << count << endl;
    }
}

自守数

题目描述

自守数是指一个数的平方的尾数等于该数自身的自然数。例如:25^2 = 625,76^2 = 5776,9376^2 = 87909376。请求出n以内的自守数的个数。

输入

int型整数。

输出

n以内自守数的数量。

样例输入 Copy

2000

样例输出 Copy

8
#include<algorithm>
#include<math.h>
#include<iostream>
using namespace std;
int fun(int num)
{
    int c = 0;
    while (num)
    {
        num /= 10;
        c++;
    }
    return c;
}
int main() {
    int n;
    while (cin >> n)
    {
        if (n >= 100000000)
            cout << 16 << endl;
        else
        {
            int ans = 0;
            for (int i = 0; i <= n; i++)
            {
                int cnt = fun(i);
                int m = pow(10, cnt);
                long long mul = (long long)i * (long long)i;
                if (mul % m == i)
                {
                    ans++;
                    
                }
            }
            cout << ans << endl;
        }
    }
 
 
    return 0;
}

相聚HNUCM校园食堂

题目描述

HNUCM的食堂重新装修了,小明决定约上朋友去食堂相聚,在食堂里,小明看到了M位男同学,N位女同学,小明是一个颜值控,因此他对每一位男生和女生都有一个颜值打分,他心里yy着想为这些单身狗们进行配对,小明真是一个关心同学的人!但小明认为配对同学的颜值之差不能超过5,注意必须是一位男同学和一位女同学才能配对,虽然小明对于可以配对的人数已经有了答案,但他想考考你的编程能力,因此他想请你帮他用编程算一下最多可以配对多少个人。(本题介绍仅作题目背景使用,无任何其他观点)

输入

每个测试文件仅有一条测试数据。
第一行输入M,N,分别表示男同学的数量,女同学的数量。(1<=M<=100,1<=N<=100)
第二行输入M个正整数,分别表示男同学们的颜值。
第三行输入N个正整数,分别表示女同学们的颜值。
注意,所有人的颜值分数范围在[1,100]

输出

输出最多可以配对的总人数。

样例输入 Copy

5 4
10 65 23 67 80
5 15 60 90

样例输出 Copy

4

提示

样例中第一位男同学和第一位女同学配对,第二位男同学和第三位女同学配对。

#include<iostream>
#include<algorithm>
using namespace std;
struct stu
{
    int temp;
    int id;
}a[10005], b[10005];
int cmp(stu a, stu b)
{
    return a.temp < b.temp;
}
int main()
{
    int n, m;
    while (~scanf("%d %d", &n, &m))
    {
        for (int i = 0; i < n; i++)
        {
            scanf("%d", &a[i].temp);
            a[i].id = i;
        }
        for (int i = 0; i < m; i++)
        {
            scanf("%d", &b[i].temp);
            b[i].id = i;
        }
        sort(a, a + n, cmp);
        sort(b, b + m, cmp);
        int num = 0;
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < m; j++)
            {
                if (abs(a[i].temp - b[j].temp) <= 5 && a[i].id != -1 && b[j].id != -1)
                {
                    num++;
                    a[i].id = -1;
                    b[j].id = -1;
                    continue;
                }
            }
        }
        printf("%d\n", num * 2);
    }
    return 0;
}

马的遍历问题 

题目描述

在5*4的棋盘中,马只能走斜“日”字。马从位置(x, y)处出发,把棋盘的每一格都走一次,且只走一次,请找出所有路径。

输入

x,y,表示马的初始位置。

输出

将每一格都走一次的路径总数,如果不存在该路径则输出“No solution!”。

样例输入 Copy

1 1
2 2

样例输出 Copy

32
No solution!

#include <stdio.h>
#include <stdlib.h>
int A[200][200];
int n = 5;
int m = 4;
int count = 0;
int fx[8] = { 1,2,2,1,-1,-2,-2,-1 };
int fy[8] = { 2,1,-1,-2,-2,-1,1,2 };
int check(int x, int y) {
 
    if (x >= 1 && x <= n && y >= 1 && y <= m && A[x][y] == 0)
 
        return 1;
 
    else return 0;
 
}
    void solve(int x, int y, int step) {
        int nextx;
        int nexty;
        A[x][y] = step;
        if (n * m == step) count++;
        for (int i = 0; i <= 7; i++)
        {
            nextx = x + fx[i];
            nexty = y + fy[i];
            if (check(nextx, nexty))
                solve(nextx, nexty, step + 1);
 
        }
 
        A[x][y] = 0;
 
    }
 
 
int main() {
    int x;
    int y;
 
 
    while (~scanf("%d %d", &x, &y)) {
        solve(x, y, 1);
        if (count != 0)
            printf("%d", count);
 
        else {
            printf("No solution!");
        }
        printf("\n");
        count = 0;
    }
    return 0;
 
}
 

图的m着色问题

题目描述

 给定无向连通图G和m种不同的颜色。用这些颜色为图G的各顶点着色,每个顶点着一种颜色。是否有一种着色法使G中每条边的2个顶点着不同颜色,请输出着色方案。

输入

输入第一行包含n,m,k分别代表n个结点,m条边,k种颜色,接下来m行每行有2个数u,v表示u和v之间有一条无向边,可能出现自环边,所以请忽略自环边。

输出

输出所有不同的着色方案,且按照字典序从小到大输出方案。

样例输入 Copy

3 3 3
1 2
1 3
2 3

样例输出 Copy

1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
#include<stdio.h>
#include <stdlib.h>
#include<math.h>
 
int a[1000][1000]; 
int color[1000];
 
int check(int t, int i) {
    for (int j = 1; j < t; j++) {
        if (a[t][j] == 1 && color[j] == i) 
            return 0;  
    }
    return 1;
}
 
 
void solve(int t, int n, int k) {
    if (t > n) { 
        for (int i = 1; i < n + 1; i++)
            printf("%d ", color[i]);
        printf("\n");
    }
    else {
        for (int i = 1; i <= k; i++) {
            if (check(t, i)) {
                color[t] = i;
                solve(t + 1, n, k);
            }
        }
    }
}
 
int main()
{
    int n, m, k;
    while (~(scanf("%d%d%d", &n, &m, &k))) {
        for (int i = 0; i < n + 1; i++) {
            color[i] = 0;
            for (int j = 0; j < n + 1; j++)
                a[i][j] = 0;
        }
        int x, y;
        for (int i = 0; i < m; i++) {
            scanf("%d %d", &x, &y);
            a[x][y] = 1;
            a[y][x] = 1;
        }
        solve(1, n, k);
    }
    return 0;
}

  素数环

题目描述

现有1,2,3...,n,要求用这些数组成一个环,使得相邻的两个整数之和均为素数,要求你求出这些可能的环。

输入

输入正整数n。

输出

输出时从整数1开始逆时针输出,同一个环只输出一次,且满足条件的环应按照字典序从小到大输出。
注:每一个环都从1开始。

样例输入 Copy

6

样例输出 Copy

1 4 3 2 5 6
1 6 5 2 3 4
#include<stdio.h>
#include <stdlib.h>
#include<math.h>
int a[20];
int used[20];
int sushu(int n) {
    for (int i = 2; i < n; i++) {
        if (n % i == 0) return 0;
    }
    return 1;
}
 
int check(int t, int i, int n) {
    if (used[i] || !sushu(i + a[t - 1])) {
        return 0;
    }
    else {
        if (t == n && !sushu(a[1] + i)) return 0;
        else
            return 1;
    }
}
 
void solve(int t, int n) {
    if (t > n) {
        for (int i = 1; i < n + 1; i++)
            printf("%d ", a[i]);
        printf("\n");
        return;
    }
    else {
        for (int i = 2; i <= n; i++) {
            if (check(t, i, n)) {
                used[i] = 1;
                a[t] = i;
                solve(t + 1, n);
                used[i] = 0;
            }
        }
    }
}
int main()
{
    int n;
    while (~(scanf("%d", &n))) {
        for (int i = 1; i < n + 1; i++) {
            a[i] = 0;
            used[i] = 0;
        }
        a[1] = 1;
        used[1] = 1;
        solve(2, n);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值