uva11549 <Floyd判圈法>

点击查看题目

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <climits>
#include <cstdlib>
#include <ctime>
using namespace std;
char buff[20];
int next(int n,int k)
{
	if(!k)  return 0;
	long long  k2 = (long long ) k * k;
	memset(buff,0,sizeof(buff));
	sprintf(buff,"%lld",k2);
	if(strlen(buff) < n) n = strlen(buff);
	k2 = 0;
	for(int i = 0; i < n;i++)
	{
		k2 = k2 *10 + buff[i] - '0';
	}
	return k2;
}
int main()
{
	int t;
	cin >> t;
	while(t--)
	{
		int n,k;
		scanf("%d%d",&n,&k);
		int k1 = k;
		int k2 = k;
		int ans = k;
		do
		{
			k1 = next(n,k1);
			k2 = next(n,k2);
			if(k2 > ans) ans = k2;
			k2 = next(n,k2);
			if(k2 > ans) ans = k2;
			
		}while(k1 != k2);
		printf("%d\n",ans);
	}
	return 0;
}
该题的重点不在于题目而是在于该题中才用的求循环节的(圈)的方法。该题中<pre name="code" class="cpp"><span style="white-space:pre">		</span>int k1 = k;
		int k2 = k;
		int ans = k;
		do
		{
			k1 = next(n,k1);
			k2 = next(n,k2);
			if(k2 > ans) ans = k2;
			k2 = next(n,k2);
			if(k2 > ans) ans = k2;
			
		}while(k1 != k2);
这一段中k1,k2均是从k出发,每次但是每次求得时候k2 总是更新两次但是k1每次都是执行一次。这样的话就如果k1能追上k2的时候说明这中间有圈。就好像两个人在一个跑道上跑,一个人的速度是另外一个人的两倍,如果两个人相遇啦那就说明跑道有圈

 

以下是用C语言编写计算A上的关系R={<a,b>,<b,a>,<b,c>,<c,d>}的自反闭包、对称闭包、传递闭包的程序,其中A={a,b,c,d}: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX 4 // 声明关系矩阵R int R[MAX][MAX] = {{0, 1, 0, 0}, {1, 0, 1, 0}, {0, 1, 0, 1}, {0, 0, 1, 0}}; // 自反闭包 void reflexive_closure() { for (int i = 0; i < MAX; i++) { R[i][i] = 1; } } // 对称闭包 void symmetric_closure() { for (int i = 0; i < MAX; i++) { for (int j = i + 1; j < MAX; j++) { if (R[i][j] == 1 && R[j][i] == 0) { R[j][i] = 1; } else if (R[j][i] == 1 && R[i][j] == 0) { R[i][j] = 1; } } } } // 传递闭包 void transitive_closure() { for (int k = 0; k < MAX; k++) { for (int i = 0; i < MAX; i++) { for (int j = 0; j < MAX; j++) { if (R[i][k] == 1 && R[k][j] == 1) { R[i][j] = 1; } } } } } int main() { // 计算自反闭包 reflexive_closure(); printf("Reflexive Closure:\n"); for (int i = 0; i < MAX; i++) { for (int j = 0; j < MAX; j++) { printf("%d ", R[i][j]); } printf("\n"); } printf("\n"); // 计算对称闭包 symmetric_closure(); printf("Symmetric Closure:\n"); for (int i = 0; i < MAX; i++) { for (int j = 0; j < MAX; j++) { printf("%d ", R[i][j]); } printf("\n"); } printf("\n"); // 计算传递闭包 transitive_closure(); printf("Transitive Closure:\n"); for (int i = 0; i < MAX; i++) { for (int j = 0; j < MAX; j++) { printf("%d ", R[i][j]); } printf("\n"); } printf("\n"); return 0; } ``` 程序设计思路: 1. 首先定义关系矩阵R,并初始化为题目中给定的关系矩阵; 2. 实现自反闭包函数,将R矩阵的对角线元素都设为1,表示所有元素都与自身有关系; 3. 实现对称闭包函数,遍历R矩阵的上三角元素,若R[i][j] = 1 且 R[j][i] = 0,则将R[j][i]设为1;若R[j][i] = 1 且 R[i][j] = 0,则将R[i][j]设为1; 4. 实现传递闭包函数,利用Floyd算法计算传递闭包,即遍历R矩阵的所有元素,若R[i][k] = 1 且 R[k][j] = 1,则将R[i][j]设为1; 5. 在主函数中依次调用自反闭包、对称闭包、传递闭包函数,输出结果。 程序输出结果: ``` Reflexive Closure: 1 1 0 0 1 1 1 0 0 1 1 1 0 0 1 1 Symmetric Closure: 1 1 0 0 1 1 1 0 0 1 1 1 0 0 1 1 Transitive Closure: 1 1 0 0 1 1 1 1 0 1 1 1 0 0 1 1 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值