SDUT- 2506-完美网络

本文介绍了两种构建完美网络的方法:一种是通过简单的遍历检查每个节点的连接数;另一种使用优先队列优化处理过程。目的是确保每个节点恰好连接两个其他节点。

题意很明确

让去构建一个完美网络,其实是要求每一个点,有两个点相连

1.水过的

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int dis[15000];

int main()
{
    int n, t, m,i;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        for(i = 0; i <= n; i++)
            dis[i] = 0;
        for(i = 0; i < m; i++)
        {
            int u, v;
            scanf("%d%d",&u,&v);
            dis[u]++;
            dis[v]++;
        }
        int ans = 0;
        for(i = 1; i <= n; i++)
        {
            if(dis[i] < 2)
                ans++;
        }
        printf("%d\n",(ans+1)/2);
    }
    return 0;
}
 
这个代码,有点问题,但是过了,看来数据很水啊

2.优先队列

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
#include<queue>
#define Maxn 10010
int dis[Maxn];
using namespace std;
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        priority_queue<int,vector<int>,greater<int> > que;
        int n, m;
        scanf("%d%d",&n,&m);
        for(int i = 0; i <= n; i++)
            dis[i] = 0;
        for(int i = 0; i < m; i++)
        {
            int u, v;
            scanf("%d%d",&u,&v);
            dis[u]++;
            dis[v]++;
        }
        for(int i = 1; i <= n; i++)
            que.push(dis[i]);
        int ans = 0;
        while(que.top()<2)
        {
            int x = que.top();
            que.pop();
            int y = que.top();
            que.pop();
            x++;
            y++;
            que.push(x);
            que.push(y);
            ans++;
        }
        printf("%d\n",ans);
    }
    return 0;
}


<think>根据用户查询,用户需要查找关于"7-11 sdut C语言实验 完美的素数"的内容。参考引用内容[1]是关于"7-7 sdut-C语言实验-完美的素数",以及引用[2]和[3]分别是关于排序和递归的内容。虽然引用[1]是7-7题,但题目名称完全一致,因此我们推测7-11可能是7-7的笔误,或者同一实验的不同版本,故以引用[1]为基础进行解答。 引用[1]的描述:素数又称质数,指大于1的自然数,除了1和自身外不能被其他自然数整除的数。完美素数的定义为:如果一个素数的每一位数字之和也是一个素数,则该素数为完美的素数。 因此,我们需要编写程序:输入一个正整数,判断它是否为完美的素数(即本身是素数且各位数字之和也是素数)。 步骤分析: 1. 判断一个数是否为素数(质数):从2到该数的平方根,看是否有整除因子。 2. 计算一个数的各位数字之和。 3. 判断该数本身和其各位数字之和是否都是素数。 注意:题目要求输入一个正整数,但未明确范围,假设在int范围内。 程序思路: 1. 编写判断素数的函数isPrime(int n):注意1不是素数,2是素数。对于负数、0和1,直接返回0(不是素数)。对于2,返回1(是素数)。对于大于2的数,判断能否被2整除,然后检查从3开始的奇数直到sqrt(n)(包含sqrt(n)的整数部分)。 2. 编写计算各位数字之和的函数digitSum(int n):使用循环每次取最低位,累加后去掉最低位。 3. 主函数:读入正整数n,先判断n是否为素数,如果不是则直接输出“No”;如果是,再计算其各位数字之和s,判断s是否为素数,如果是则输出“Yes”,否则输出“No”。 注意边界情况:题目提到大于1的自然数,所以输入至少为2。 根据引用[1]的描述,我们编写如下代码: ```c #include <stdio.h> #include <math.h> // 判断素数函数 int isPrime(int n) { if (n <= 1) return 0; // 1和负数、0都不是素数 if (n == 2) return 1; // 2是素数 if (n % 2 == 0) return 0; // 偶数(除2)不是素数 int sqr = (int)sqrt(n*1.0); // 平方根 for (int i = 3; i <= sqr; i += 2) { if (n % i == 0) return 0; } return 1; } // 计算各位数字之和 int digitSum(int n) { int sum = 0; while (n) { sum += n % 10; n /= 10; } return sum; } int main() { int n; while (scanf("%d", &n) != EOF) { if (isPrime(n)) { int s = digitSum(n); if (isPrime(s)) { printf("Yes\n"); } else { printf("No\n"); } } else { printf("No\n"); } } return 0; } ``` 注意:题目可能要求多次输入,所以我们用循环读取直到文件结束(EOF)。 如果用户一次只输入一个数,也可以不用循环。但题目输入格式未明确,引用中显示输入格式为“7-7”题目的输入格式为“输入格式:”,无具体说明,但通常实验题目会要求处理多个测试用例,所以这里采用循环直到EOF。 另外,如果题目明确只有一次输入,则取消循环,但为了通用性,我们使用循环。 说明:该程序先判断n是否为素数,如果不是直接输出"No";如果是,再计算各位数字之和s,并判断s是否为素数,是则输出"Yes",否则输出"No"。 §§相关问题§§ 1. 如何优化判断素数的效率? 2. 如果输入的数字非常大(比如10^9),如何进一步提高计算各位数字之和的效率? 3. 完美素数还有其他定义方式吗? </think> 以下是关于“7-11 sdut C语言实验 完美的素数”的完整解答。根据实验要求,需要判断一个素数是否为“完美的素数”:即该素数本身是质数,且其各位数字之和也是质数。 ### 问题分析 1. **完美素数定义** - 素数:大于1的自然数,且只能被1和自身整除(如 2, 3, 5, 7...) - 完美素数:若素数$n$的各位数字之和$s$也是素数,则$n$为完美素数(如 23:$2+3=5$,5是素数 → 完美素数)[^1] 2. **程序实现步骤** - 步骤1:编写判断素数的函数 `isPrime(int n)` - 步骤2:编写计算各位数字之和的函数 `digitSum(int n)` - 步骤3:主函数中判断输入数是否同时满足: - $n$是素数 - $n$的各位数字之和是素数 --- ### 完整代码实现 ```c #include <stdio.h> #include <math.h> // 判断素数函数(时间复杂度:O(√n)) int isPrime(int n) { if (n <= 1) return 0; // 1不是素数 if (n == 2) return 1; // 2是素数 if (n % 2 == 0) return 0; // 排除偶数 int sqrt_n = (int)sqrt(n); for (int i = 3; i <= sqrt_n; i += 2) { if (n % i == 0) return 0; } return 1; } // 计算数字各位之和 int digitSum(int n) { int sum = 0; while (n > 0) { sum += n % 10; // 取最后一位 n /= 10; // 去掉最后一位 } return sum; } int main() { int num; scanf("%d", &num); // 输入正整数 if (isPrime(num)) { int sum = digitSum(num); if (isPrime(sum)) { printf("Yes\n"); // 是完美素数 } else { printf("No\n"); // 数位和不是素数 } } else { printf("No\n"); // 本身不是素数 } return 0; } ``` ### 代码说明 1. **素数判断优化** - 用$\sqrt{n}$作为循环上限减少计算量 - 跳过偶数检测(除2外) - 时间复杂度:$O(\sqrt{n})$ 2. **输入输出示例** - 输入:`23` → 输出:`Yes`($23$是素数,$2+3=5$是素数) - 输入:`13` → 输出:`No`($13$是素数,但$1+3=4$不是素数) - 输入:`100` → 输出:`No`(100不是素数) --- ### 拓展应用 该方法可用于解决: 1. 密码学中的数字特性验证 2. 数学谜题(如“素数环”问题) 3. 算法竞赛中的数值特性题(如Project Euler) ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值