1. 程式人生 > >OJ 系列之常規練習題(一)

OJ 系列之常規練習題(一)

1、求M的n次方最後三位

【問題描述】
正整數M 的N次方有可能是一個非常大的數字,我們只求該數字的最後三位

例1:比如輸入5和3 ,5的3次方為125,則輸出為125

例2:比如輸入2和10 2的10次方為1024 ,則輸出結果為24

例3:比如輸入111和5 111的5次方為116850581551,則輸出結果為551

#include <stdlib.h>
#include "oj.h"


unsigned int  GetLastThreeNumOfResult (unsigned int  m, unsigned int  n)
{   
    int i = 0
; int result = 1; for(i=0;i<n;i++) { result = m*result%1000; } return result; }

2、向升序單向連結串列中插入一個節點

需要注意一點就是第一個節點前插入節點。


#include "OJ.h"

struct ListNode {
    int       m_nKey;
    ListNode* m_pNext;
};

/*
功能: 輸入一個升序單向連結串列和一個連結串列節點,向單向連結串列中按升序插入這個節點。
      輸入為空指標的情況視為異常,另外不考慮節點值相等的情況。

輸入: ListNode* pListHead  單向連結串列
      ListNode* pInsertNode 新插入節點

輸出: ListNode* pListHead  單向連結串列

返回: 正常插入節點返回連結串列頭指標,其它異常返回空指標
*/
ListNode* InsertNodeToList(ListNode* pListHead, ListNode* pInsertNode) { if(!pListHead ||!pInsertNode) return (ListNode*)NULL; /*1.新增一個頭結點,處理插入的節點是在第一個節點之前*/ ListNode* dummy = (ListNode*)malloc(sizeof(ListNode)); dummy->m_pNext = pListHead; ListNode* p = pListHead; ListNode*
pre = dummy; while(p){ if(p->m_nKey > pInsertNode->m_nKey){ break; } pre = p; /*保留前一個節點*/ p = p->m_pNext; } pInsertNode->m_pNext = p; pre->m_pNext = pInsertNode; pListHead = dummy->m_pNext; free(dummy); return pListHead; }

3、刪除連結串列中的重複節點、剩餘節點逆序輸出

解題思路:

  • 1、將連結串列節點的資料放入一個數組中mydata
  • 2、對這個mydata進行去重處理(本題最主要工作),剩餘元素就是我們想要的資料。
  • 3、申請節點地址,逆序輸出
#include <stdlib.h>
#include "oj.h"
#include <vector>
using namespace std;

typedef struct strNode {
    int data;
    strNode * pstrNext;
}strNode;

/*
功能:  輸入一個不帶頭節點的單向連結串列(連結串列的節點數小於100),
刪除連結串列中內容重複的節點(重複的節點全部刪除),剩餘的節點逆序倒排。
輸入:   pstrIn: 輸入一個不帶頭節點的單向連結串列  
輸出:   pstrOut:刪除內容重複的節點後,
逆序排列的連結串列(不帶頭節點,連結串列第一個節點的記憶體已經申請)。

返回:

示例:
輸入連結串列的內容依次為 6,7,8,8,9,10,6
則輸出連結串列的內容依次應該是 10,9,7

*/
void move(int *a,int index,int count)
{
    int in=index;
    /*覆蓋原來的資料*/
    for(int i=0;i<count-1;i++) {
        a[in]=a[in+1];
        in++;
    }
}

int iChanProcess(strNode * pstrIn,strNode * pstrOut)
{
    if(!pstrIn||!pstrOut)
        return 0;
    /*最大節點個數為100個*/
    int mydata[100];
    strNode *pstrIntemp = pstrIn;
    int mydataLen = 0;
    /*1.取出節點的資料*/
    while(pstrIntemp) {
        mydata[mydataLen] = pstrIntemp->data;
        pstrIntemp = pstrIntemp->pstrNext;
        mydataLen ++;
    }
    int i = 0,j = 0;
    int temp = 0;
    int moveFlag = 0;
    /*2.除去相同元素*/
    for(i=0;i<mydataLen;i++) {
        temp = mydata[i];
        for(j = i+1;j<mydataLen;j++) {
            if(temp==mydata[j]) {
                move(mydata,j,mydataLen-j);
                moveFlag = 1;
                mydataLen--;
            }
        }
        if(moveFlag) {
            move(mydata,i,mydataLen-i);
            mydataLen--;
            moveFlag = 0;
        }
    }
    /*頭結點地址已經申請*/
    strNode *MypstrOut=pstrOut;
    MypstrOut->data=mydata[mydataLen-1];
    /*3.逆序輸出,申請節點地址*/
    for(int tep=mydataLen-2;tep>=0;tep--) {
        strNode* padd = (strNode *)malloc(sizeof(strNode));
        padd->data = mydata[tep];/*資料*/
        MypstrOut->pstrNext = padd;
        padd->pstrNext = NULL;
        MypstrOut = MypstrOut->pstrNext;
    }

    return 0;
}

/* 釋放連結串列 */
void vFreeChan(strNode * pstrChan)
{
    strNode *p,*pstrd;
    pstrd=pstrChan;
    while(pstrd) {
        p=pstrd->pstrNext; /*儲存下一個節點*/
        free(pstrd);
        pstrd=p;
    }    
    return;
}

4、二維陣列的列排序

程式如下,不過時間複雜度比較高,可以使用更好的排序演算法(快速排序)代替冒泡。

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

#include "oj.h"

// 功能:排列一個m行n列 大小的陣列
// 輸入: int * pArray 指向陣列第一個元素的指標,m為行數, n為列數 ,請按第i列排列
// 輸出:按第i列排序完成後的陣列放到入參指定的地址中    (i的取值範圍 1 - n)  
// 返回:
void RangeArray(int * pArray,unsigned int  m, 
                unsigned int  n,unsigned int  i)  
{     
    i--;  
    if (pArray == NULL || m<=0 || n<=0 || i<0 || i>=n) {  
        return;  
    } 
    int j = 0,k = 0;
    int i2 = 0;
    int aa = 0,bb = 0;
    int temp = 0;
    int nIndex = 0;
    /*前兩個for目的是冒泡法排序,第三個for是列*/
    for (j=0;j<m;j++) {  /*行*/
        for (k=j+1;k<m;k++) {  
            for (i2 = i; i2<n; i2++) {  /*列*/
                aa = *(pArray+j*n+i2);  /*第j行第i2列資料*/
                bb = *(pArray+k*n+i2);  /*第j+1行第i2列資料*/
                if (*(pArray+j*n+i2) > *(pArray+k*n+i2)) {  
                    /*交換兩行資料*/
                    for (nIndex=0;nIndex<n;nIndex++) {  
                        temp = pArray[j*n + nIndex];  
                        pArray[j*n + nIndex] =  pArray[k*n + nIndex];  
                        pArray[k*n + nIndex] = temp;  
                    }  
                    break;
                /*兩個數相等,需要比較下一列的資料*/
                } else if (*(pArray+j*n+i2) == *(pArray+k*n+i2)) {  
                    continue;  
                /*次序正確,無需變動*/
                } else if(*(pArray+j*n+i2) < *(pArray+k*n+i2)) {  
                    break;  
                }  
            }  
        }  
    }  
}  

5、取給定正整數的指定bit位開始的指定長度的資料

startbit-bitlen+1理解為bit位從右向左數的,比如11011,startbit為3、bitlen為3,該數為101,因此原數字需要先左移到startbit-bitlen+1 = 1,移動到101最低位。

/*
Description  
取給定正整數的指定bit位開始的指定長度的資料。bit位從右向左從0開始計算。
Prototype
 unsigned int GetBitsValue(unsigned int input, unsigned int startbit,unsigned int bitlen)
Input Param 
         input      輸入的整數
         startbit   需要獲取的開始bit
         bitlen     需要獲取的bit長度
Output Param 
         無
Return Value
         對應的bit取值
*/

unsigned int GetBitsValue(unsigned int input, unsigned int startbit, 
                                unsigned int bitlen)
{
    /*在這裡實現功能*/
    if(startbit>31||bitlen>32||(bitlen>startbit))
        return -1;

    if(bitlen==0)
        return -1;
    unsigned int i = 0;
    input = input>>(startbit-bitlen+1);
    int sum = 1;
    int temp = 1;
    for(i=1;i<bitlen;i++) {
        temp  = (temp<<1);
        sum = sum + temp;
    }
    input = input&sum;

    return input;
}

6、兔子產子

假定你有一雄一雌一對剛出生的兔子,它們在長到一個月大小時開始交配,在第二月結束時,雌兔子產下另一對兔子,過了一個月後它們也開始繁殖,如此這般持續下去。每隻雌兔在開始繁殖時每月都產下一對兔子,假定沒有兔子死亡,在一年後總共會有多少對兔子?
在一月底,最初的一對兔子交配,但是還只有1對兔子;在二月底,雌兔產下一對兔子,共有2對兔子;在三月底,最老的雌兔產下第二對兔子,共有3對兔子;在四月底,最老的雌兔產下第三對兔子,兩個月前生的雌兔產下一對兔子,共有5對兔子;……如此這般計算下去,兔子對數分別是:1, 1, 2, 3, 5, 8, 13, 21, 34, 55,89, 144, …看出規律了嗎?從第3個數目開始,每個數目都是前面兩個數目之和。這就是著名的斐波那契(Fibonacci)數列。

#include <stdlib.h>
#include "oj.h"
// 功能:獲取第nValue1個月出生多少對兔子
// 輸入: nValue1為正整數
// 輸出:無
// 返回:第nValue1個月出生多少對兔子


unsigned int GetBirthRabbitNum(unsigned int  nValue1)
{
    if(nValue1==0) {
        return 0;
    }
    if(nValue1==1||nValue1==2) {
        return 1;
    }
    int sum = 1;
    int sumpre = 1;
    int i = 0;
    int result = 0;
    for(i=3;i<=nValue1;i++) {
        result = sum+sumpre;
        sumpre = sum;
        sum = result;
    }

    return result;
}

7、報文轉換

/*
功能:
    將給定的報文按規則轉換成另一個報文後輸出。
    轉換規則如下:
    報文中如果出現0x7E,轉義成為2個位元組0x7D 0x5E,如果出現0x7D,轉義成為2個位元組0x7D 0x5D。最後在報文頭尾各加上一個0x7E定界。

    示例(每個位元組以十六進位制數表示)
    給定原始報文:1D 2B 3C 4D 5E 7E 6F 7D 7E
    轉換後的報文:7E 1D 2B 3C 4D 5E 7D 5E 6F 7D 5D 7D 5E 7E

輸入:
char* pInput: 給定的輸入報文,記憶體空間由呼叫者申請和釋放
int iLen: 給定報文的長度   
輸出:
char* pOutput:轉換後的報文,記憶體空間由呼叫者申請和釋放
返回:
int: 成功 0, 失敗 -1
*/

本文處理是先在棧中申請一個足夠大的陣列,長度為10000,假設報文足夠,本程式不適用。

int PktTrans(char* pInput, int iLen, char* pOutput)
{

    if(pInput==NULL||*pInput=='\0'|| 
      (iLen < 0) || (iLen >= 100)||pOutput==NULL) {
        return -1;
    }
    if(iLen==0)
        return 0;

    char temp[10000];

    int i=0,j=0;

    for(i = 0;i<iLen;i++)
    {   
        if(pInput[i]==0x7E) {   
            temp[j++]=0x7D;
            temp[j++]=0x5E; 
        } else if(pInput[i]==0x7D) {
            temp[j++]=0x7D;
            temp[j++]=0x5D;
        } else {
            temp[j]=pInput[i];
            j++;
        }
    }
    temp[j]='\0';

    pOutput[0]=0x7E;

    for(int k=0;k<j;k++) {
        pOutput[k+1]=temp[k];
    }
    pOutput[j+1]=0x7E;
    pOutput[j+2]='\0';

    return 0;       
}

8、計算二進位制數的0的個數

#include <stdio.h>

int bit_zero_cal(unsigned int n) 
{
    int count = 0;

    while(n) {

        if(!(n&1))
            count ++;
        n = n>>1;
    }
    printf("%d\n",count);
    return count;
}
int main()
{
    unsigned int n;
    scanf("%d",&n);
    bit_zero_cal(n);
    getchar();
}

9、簡單密碼破解

/*
密碼是我們生活中非常重要的東東,我們的那麼一點不能說的祕密就全靠它了。
哇哈哈. 接下來淵子要在密碼之上再加一套密碼,雖然簡單但也安全。

假設淵子原來一個BBS上的密碼為zvbo9441987,為了方便記憶,
他通過一種演算法把這個密碼變換成YUANzhi1987,這個密碼是他的名字和出生年份,怎麼忘都忘不了,
而且可以明目張膽地放在顯眼的地方而不被別人知道真正的密碼。

他是這麼變換的,大家都知道手機上的字母: 
1--1, abc--2, def--3, ghi--4, jkl--5, mno--6, 
pqrs--7, tuv--8 wxyz--9, 0--0,
就這麼簡單,淵子把密碼中出現的小寫字母都變成對應的數字,數字和其他的符號都不做變換,

宣告:密碼中沒有空格,而密碼中出現的大寫字母則變成小寫之後往後移一位,
如:X,先變成小寫,再往後移一位,不就是y了嘛,簡單吧。記住,z往後移是a哦。


*/

程式碼實現

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

void Decoding(char *inputCodestr) 
{
    if(!inputCodestr)
        return;
    int inputCodestrLen = strlen(inputCodestr);
    int i = 0;
    while(inputCodestr[i]!='\0') {
        if(inputCodestr[i]>='A'&&inputCodestr[i]<='Y') {
            inputCodestr[i]=inputCodestr[i]+'a'-'A'+1;
        }
        else if(inputCodestr[i]=='Z') {
            inputCodestr[i]='a';
        }
        else if(inputCodestr[i]>='a'&&inputCodestr[i]<='c') {
            inputCodestr[i]='2';
        }
        else if(inputCodestr[i]>='d'&&inputCodestr[i]<='f') {
            inputCodestr[i]='3';
        }
        else if(inputCodestr[i]>='g'&&inputCodestr[i]<='i') {
            inputCodestr[i]='4';
        }
        else if(inputCodestr[i]>='j'&&inputCodestr[i]<='l') {
            inputCodestr[i]=='5';
        }
        else if(inputCodestr[i]>='m'&&inputCodestr[i]<='o') {
            inputCodestr[i]='6';
        }
        else if(inputCodestr[i]>='p'&&inputCodestr[i]<='s') {
            inputCodestr[i]='7';
        }
        else if (inputCodestr[i]>='t'&&inputCodestr[i]<='v') {
            inputCodestr[i]='8';
        }
        else if(inputCodestr[i]>='w'&&inputCodestr[i]<='z') {
            inputCodestr[i]='9';
        }
        else {
            inputCodestr[i]=inputCodestr[i];
        }
        i++;
    }

    printf("%s\n",inputCodestr);
}

int main()
{
    char inputCodestr[100];

    gets(inputCodestr);
    Decoding(inputCodestr);
    return 0;
}

10、密碼驗證合格程式

/*
密碼要求:
1.長度超過82.包括大小寫字母.數字.其它符號,以上四種至少三種
3.不能有相同長度超2的子串重複
說明:長度超過2的子串
輸入:  
一組或多組長度超過2的子符串。每組佔一行  
輸出:  
如果符合要求輸出:OK,否則輸出NG

每行輸出對應一組輸入的結果;


樣例輸入:   021Abc9000
            021Abc9Abc1
            021ABC9000
            021$bc9000

樣例輸出: OK
          NG
          NG
          OK
*/

本題難點在於如何實現多行輸入:while(scanf(“%s”,inputstr)!=EOF)
程式碼實現

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

void judge(char inputstr[])
{
    if(!inputstr) {
        printf("NG");
        return;
    }
    int i = 0,j = 0;
    int inputstrLen = strlen(inputstr);
/*1.條件1---長度超過8位*/
    if(inputstrLen<=8) {
        printf("NG");
        return;
    }
    int numCount = 0;
    int LowercaseLettersCount = 0;
    int CapitalLettersCount = 0;
    int OtherCharactersCount = 0;

    for (i=0;i<inputstrLen;i++) {
        if(inputstr[i]>='0' && inputstr[i]<='9')
            numCount ++;
        else if(inputstr[i]>='a' && inputstr[i]<='z')
            LowercaseLettersCount ++;
        else if(inputstr[i]>='A' && inputstr[i]<='Z')
            CapitalLettersCount ++;
        else {
            OtherCharactersCount ++;
        }
    }
/*2.條件2---至少三種字元*/
    if(numCount==0) {
        if(LowercaseLettersCount==0||CapitalLettersCount==0||OtherCharactersCount==0) {
            printf("NG");   
            return;
        }
    } else if(LowercaseLettersCount==0) {
        if(CapitalLettersCount==0||OtherCharactersCount==0) {
            printf("NG");   
            return;
        }
    } else if(CapitalLettersCount==0) {
        if(OtherCharactersCount==0) {
            printf("NG");   
            return;
        }
    }
    char inputStrtemp[2];
/*3.條件3---相同長度超2的子串重複*/
    for (i=0;i<inputstrLen-1;i++) {
        inputStrtemp[0] = inputstr[i];
        inputStrtemp[1] = inputstr[i+1];
        for(j=i+2;j<inputstrLen-1;j++) {
            if(inputstr[j]==inputStrtemp[0]&&inputstr[j+1]==inputStrtemp[1]) {
                printf("NG");   
                return;
            }

        }
    }

    printf("OK");   
}


int main()
{
    char inputstr[1024];

    while(scanf("%s",inputstr)!=EOF) {
        judge(inputstr);
    }
    return 0;
}


相關推薦

OJ 系列常規練習題

1、求M的n次方最後三位 【問題描述】 正整數M 的N次方有可能是一個非常大的數字,我們只求該數字的最後三位 例1:比如輸入5和3 ,5的3次方為125,則輸出為125 例2:比如輸入2和10 2的10次方為1024 ,則輸出結果為24 例3:比如

OJ 常規練習題

1、識別有效的IP地址和掩碼並進行分類統計 /* 請解析IP地址和對應的掩碼,進行分類識別。要求按照A/B/C/D/E類地址歸類, 不合法的地址和掩碼單獨歸類。 所有的IP地址劃分為 A,B,C,D,E五類 A類地址1.0.0.0~126.255.255.

C#系列基礎知識點

命名規則 系列 字符 註釋 編輯器 小數類型 智能 規則 解釋 知識點一:VS啟動方法 第一種:雙擊圖標 第二種:window+R——調出cmd,輸入devenu properties 屬性的意思 知識點二:後綴名解釋 .sln 解決方案文件:包含整個解決方案的信息 .

反向教學系列——PHP入門

water oui 版本 名稱 令行 完全 技術 地址 安裝目錄 php是什麽?其實就是html的功能加強版。網頁本來在服務器上,如果客戶端問服務器索取網頁文件(xxx.html),那麽服務器就會把客戶端指定的網頁發回去。(根據我的理解,)php是因“表單”而誕生的,所謂表

反向教學系列——Django入門【不需知道web框架】

Django 教程 反向教學 一派胡言 用這東西最終是建網站的,或者是更一般意義的服務器。服務器麽,就是如果用別的電腦(“客戶機”)給它發請求,它會返回一些東西——如果給隨便某個機器發信息,它自然未必理你。要想某機器回應你,得滿足這些條件——它不處在關機狀態它能收到你的信息,你也能收到它的信息

【原創】技術系列 執行緒

作者:CppExplore 網址:http://www.cppblog.com/CppExplore/廢話不多說,詳細介紹使用執行緒的優點好處請參考baidu、google。一、執行緒使用場景。使用執行緒的方式大致有兩種:(1)流水線方式。根據業務特點,將一個流程的處理分割成多個執行緒,形成流水線的處

【原創】技術系列 狀態機

作者:CppExplore 網址:http://www.cppblog.com/CppExplore/一、狀態機描述狀態機理論最初的發展在數位電路設計領域。在數位電路方面,根據輸出是否與輸入訊號有關,狀態機可以劃分為Mealy型和Moore型狀態機;根據輸出是否與輸入訊號同步,狀態機可以劃分為非同步和

技術系列 網路模型基礎篇

全文針對linux環境。tcp/udp兩種server種,tcp相對較複雜也相對比較常用。本文就從tcp server開始講起。先從基本說起,看一個單執行緒的網路模型,處理流程如下: socket-->bind-->listen-->[accept-->

技術系列 定時器

一、 基礎知識1、時間型別。Linux下常用的時間型別有4個:time_t,struct timeval,struct timespec,struct tm。(1)time_t是一個長整型,一般用來表示用1970年以來的秒數。(2)Struct timeval有兩個成員,一個

入門到放棄node系列網路模組

前言 本文首發公眾號【一名打字員】 上一次相信大家都基本瞭解node的用法了,有做功課的童鞋肯定回去溫習了一下js的語法。這些年來js發展很快,出了很多類似許多vue、react、node等等眾所周知的玩意兒,對應的社群配套也越來越完善。好的,接下來我們補充

springboot原始碼解析-管中窺豹系列總體結構

# 一、簡介 - Springboot原始碼解析是一件大工程,逐行逐句的去研究程式碼,會很枯燥,也不容易堅持下去。 - 我們不追求大而全,而是試著每次去研究一個小知識點,最終聚沙成塔,這就是我們的springboot原始碼管中窺豹系列。 ![ 簡介 ](https://zhangbin1989.gitee.

MVC系列博客排球計分需求分析

height repl 系列 ges 優勢 針對 .... 9.png ota 項目簡介: 這是MVC系列博客之排球計分程序,該程序可以是對教練或者裁判使用的,讓教練有權限對隊員進行查詢得分情況,讓教練對隊員的優勢劣勢進行了解,以便對隊伍進行調整。 讓裁判更

Unity3D《看就明白系列讀取Txt

策劃寫Excel  ---> 程式解析Excel為Text(letter) --->程式讀取Txt   檔案路徑:   Appliction.dataPath 專案資源路徑   Application.

UART0串列埠程式設計系列 串列埠(UART0)UC/OS

一.在UC/OS中設計串列埠程式所要考慮的問題 1.     串列埠通訊資料以幀為單位進行處理,如果需要接收大量資料,則幀緩衝區規模必然很大;如果需要傳送大量資料,則可將原始資料快看作緩衝區,不需要另外再建立幀緩衝區。 2.     幀緩衝區是全域性資料結構,通常為共

設計模式問題集錦

是把 後繼 ogr data- 跟著 沒有 解釋器 space 基本實現 設計模式的主要資料是《大話設計模式》。第一階段先看看各種模式的基本概念。實現每一個模式下的樣例。然後在進行理解性的學習和掌握,靈活掌握各種模式的長處,知道某種模式適合那種狀態。如今,樣

CSS3學習系列選擇器

計算 選擇器 sky :focus ddr gree for 指定元素 學習 first-child選擇器和last-child選擇器 first-child指定第一個元素。last-child指定最後一個子元素。 例如: <!DOCTYPE html>

Python/ MySQL練習題

姓名 insert avg when 並且 記錄 有效 完全 cas Python/ MySQL練習題(一) 2、查詢“生物”課程比“物理”課程成績高的所有學生的學號 1 SELECT 2 * 3 FROM 4 ( 5 SELEC

android深入設計模式托付模式

-h listen back != new 聚合 string static data- (一)托付模式簡單介紹 托付模式是主要的設計模式之中的一個。托付。即是讓還有一個對象幫你做事情。 更多的模式,如狀態模式、策略模式、訪問者模式本質上是在更特殊的場合採用了托

JavaSE 學習筆記Java概述

environ 電子 6.0 run javase 有一點 架構 spa form 一、Java的三種技術架構: JAVAEE:Java Platform Enterprise Edition,開發企業環境下的應用程序,主要針對web程序開發; JAVASE:Java P

Java集合初探

lin 數據改變 排序。 方法 規則 找不到 集合 回收 for循環 一、集合概述、區別 集合是一種容器,數組也是一種容器 在Java編程中,裝各種各樣的對象(引用類型)的叫做容器。 為什麽出現集合類? 面向對象語言對事物的體現都是以對象的形式,所以為了方便對多個對象的操作