日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

八、求循环节

發布時間:2025/3/21 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 八、求循环节 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

八、求循環節

文章目錄

  • 八、求循環節
    • 題目描述
    • 解題思路
    • 上機代碼

題目描述

對于任意的真分數 N/M ( 0 < N < M ),均可以求出對應的小數。如果采用鏈表存儲各位小數,對于循環節采用循環鏈表表示,則所有分數均可以表示為如下鏈表形式。

輸入: N M

輸出: 整個循環節

要求: 編寫一個盡可能高效的查找循環節起始點的函數: NODE * find( NODE * head, int * n ) 。函數的返回值為循環節的起點(即圖中的指針p),n為循環節的長度。

說明:提交程序時請同時提交將分數轉換為小數的函數 change( int n, int m, NODE * head ) (前面題目中已經編寫)。

將分數轉換為小數的函數 change()我們在 六、求循環小數 中已經編寫過了,可以直接拷貝過來

預設代碼:

/* PRESET CODE BEGIN - NEVER TOUCH CODE BELOW */#include <stdio.h> #include <stdlib.h> typedef struct node { int data;struct node * next; } NODE;NODE * find( NODE * , int * ); void outputring( NODE * ); void change( int , int , NODE * ); void outputring( NODE * pring ) { NODE * p;p = pring;if ( p == NULL )printf("NULL");elsedo { printf("%d", p->data);p = p->next;} while ( p != pring );printf("\n");return; }int main() { int n, m;NODE * head, * pring;scanf("%d%d", &n, &m);head = (NODE *)malloc( sizeof(NODE) );head->next = NULL;head->data = -1;change( n, m, head );pring = find( head, &n );printf("ring=%d\n", n);outputring( pring );return 0; }/* Here is waiting for you. void change( int n, int m, NODE * head ) { }NODE * find( NODE * head, int * n ) {} *//* PRESET CODE END - NEVER TOUCH CODE ABOVE */ 測試輸入期待的輸出時間限制內存限制額外進程
測試用例 11 3ring=1
3
1秒64M0
測試用例 21 8ring=0
NULL
1秒64M0
測試用例 329 33ring=2
87
1秒64M0
測試用例 42 7ring=6
285714
1秒64M0

解題思路

change()函數我們已經編寫過了,直接拷貝過來即可,這里就只考慮find()函數的編寫

我們借助于編寫change()時的思想,將 p1、p2 設置為全局變量。這樣,判斷如果 p2 > p1 ,即可證明存在循環

存在循環,循環的長度即為 p2 - p1 的距離,否則長度為0。

仔細觀察outputring()函數發現,函數從循環節開始的位置出發,將循環節打印一圈后終止。所以我們在find()函數中越過 p1 長度的前綴,直接將循環節開始的位置返回即可。

上機代碼

#include <string.h> int p1 = 0, p2 = 0; void change(int n, int m, NODE *head ) {//初始化int shang[10010], yushu[10010];memset(shang, 0, sizeof(shang));memset(yushu, 0, sizeof(yushu));p1 = 0, p2 = 0;int flag = 0;int num = n * 10;for (int i = 0; ; i++){shang[i] = num / m;yushu[i] = num % m;for (int j = 0; j < i; j++){/* 當商和余數與之前相同時,即標志著出現循環用p1、p2記錄位置,flag=1表示存在循環 */ if(shang[j] == shang[i] && yushu[j] == yushu[i]){p1 = j;p2 = i;flag = 1;break;}}num = yushu[i] * 10;if(!num)//如果num被除盡,變為0,則沒有循環{p1 = i + 1;break;}if(flag == 1){break;}}/*根據 p1 的位置,如果沒有循環,則建立完整鏈表;如果有循環,則建立的是前綴。 */NODE *r = head;for (int i = 0; i < p1; i++){//尾插法建立鏈表NODE *q = (NODE*)malloc(sizeof(NODE));q->data = shang[i];q->next = NULL;r->next = q;r = q;}//補上循環if (flag == 1){NODE *r_save = r;for (int i = p1; i < p2; i++){NODE *q = (NODE*)malloc(sizeof(NODE));q->data = shang[i];q->next = NULL;r->next = q;r = q;}r->next = r_save->next;} }NODE * find( NODE *head, int *n ) {if(p2 > p1)//存在循環{NODE *p = head->next;//初始化//計算長度*n = p2 - p1;//越過前綴for (int i = 0; i < p1; i++){p = p->next;}return p;}else//不存在循環{*n = 0;return NULL;} }

總結

以上是生活随笔為你收集整理的八、求循环节的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。