蘇州大學(xué)2012-2014年上機復(fù)試題

2012年上機題

題目

??從服務(wù)器上下載數(shù)據(jù)文件org.dat文件以二進(jìn)制方式存放一系列整數(shù)阳啥,每個整數(shù)占4個字節(jié)。從第一個整數(shù)開始,第一個整數(shù)和第二個整數(shù)構(gòu)成一個坐標(biāo)點兜喻,依次類推泡仗,數(shù)據(jù)文件中保存了許多坐標(biāo)點數(shù)據(jù)埋虹。
??問題1:
??規(guī)定處于第一象限的坐標(biāo)點為有效點,請問數(shù)據(jù)文件中所有點的個數(shù)n為多少娩怎?有效點的個數(shù)k為多少搔课?
??問題2:
??每個有效點與坐標(biāo)原點構(gòu)成一個的矩形,請問k個有效點與坐標(biāo)原點構(gòu)成的k個矩形的最小公共區(qū)域面積為多少截亦?
??問題3:
??尋找有效點中符合下列條件的點:以該點為坐標(biāo)原點爬泥,其他有效點仍然是有效點即處于第一象限(不包括坐標(biāo)軸上的點)柬讨。輸出這些點。
??問題4:
??對所有有效點進(jìn)行分組袍啡,每個有效點有且只能屬于一個分組踩官,分組內(nèi)的點符合下列規(guī)則:若對組內(nèi)所有點的x坐標(biāo)進(jìn)行排序,點p1(x1境输,y1)在點p2(x2蔗牡,y2)后面,即x1>x2那么y1>y2.請輸出所有的分組嗅剖。

分析

??我看到有的代碼是分題做的辩越,這樣更好給分,但是我就混在一起了窗悯,因為有些功能可以同時完成区匣。
??我大概分成下面幾個部分:
??(1)讀文件,求出n和k蒋院,保存有效點亏钩。
??(2)以x的的大小由小到大進(jìn)行排序。經(jīng)過簡單處理欺旧」贸螅可以得到最小公共面積和問題三所求的點。
??(3)分組辞友。我就遍歷了栅哀,對每個點給了一個符號位。時間復(fù)雜度比較高称龙。

代碼

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

void fileRead(FILE * fp, int num[][2], int *k, int * n);
int cmp(const void* a, const void *b);
void findMinSquare(int num[][2], int k);
int divideGroup(int num[][2], int k, int group[]);

void main()
{
    FILE * fp = fopen("org.dat", "rb");
    if (fp == NULL) {
        printf("FILE OPEN ERROR!\n");
        exit(1);
    }
    // 造數(shù)據(jù)文件留拾,coor.txt中已經(jīng)存放了一些數(shù)據(jù)
    //FILE * fp = fopen("org.dat", "wb");
    //FILE * f2 = fopen("coor.txt","r");
    //if (fp == NULL || f2==NULL) {
    //  printf("FILE OPEN ERROR!\n");
    //  exit(1);
    //}
    //int t;
    //while (fscanf(f2, "%d", &t) != EOF) {
    //  fwrite(&t, sizeof(int), 1, fp);
    //}
    //fclose(f2);

    int num[1000][2], k = 0, n = 0, groupnum;
    int group[100];
    
    fileRead(fp, num, &k, &n);

    printf("所有點的個數(shù)為:%d\n", n);
    printf("支配點的個數(shù)為:%d\n", k);

    qsort(num, k, sizeof(num[0]), cmp);
    findMinSquare(num, k);

    memset(group, -1, sizeof(group));
    groupnum = divideGroup(num, k, group);
    printf("共分為%d組,具體如下:\n", groupnum);
    for (int i = 0; i < groupnum; i++) {
        printf("第%d組點為:", groupnum);
        for (int j = 0; j < k; j++) {
            if (group[j] == i) {
                printf(" (%d, %d)", num[j][0], num[j][1]);
            }
        }
        printf("\n");
    }

    fclose(fp);

}

void fileRead(FILE * fp, int num[][2], int *k, int * n) 
{
    int x, y;
    while (fread(&x, sizeof(int), 1, fp) && fread(&y, sizeof(int), 1, fp)) {
        *n = *n + 1;
        if (x > 0 && y > 0) {
            num[*k][0] = x;
            num[*k][1] = y;
            *k = *k + 1;
        }
    }
}

int cmp(const void* a, const void *b)
{
    return ((int *)a)[0] - ((int *)b)[0];
}

void findMinSquare(int num[][2], int k)
{
    int minx, miny;
    if (k == 1) {
        printf("最小公共面積是:%d\n", num[0][0] * num[0][1]);
        printf("符合要求的點的坐標(biāo)為:(%d, %d)", num[0][0], num[0][1]);
    }

    else {
        if (num[0][0] < num[1][0] && num[0][1] < num[1][1]) {
            printf("最小公共面積是:%d\n", num[0][0] * num[0][1]);
            printf("符合要求的點的坐標(biāo)為:(%d, %d)\n", num[0][0], num[0][1]);
        }
        else {
            minx = num[0][0];
            miny = num[0][1];
            for (int i = 1; i < k; i++) {
                if (minx > num[i][0]) {
                    minx = num[i][0];
                }
                if (miny > num[i][1]) {
                    minx = num[i][1];
                }
            }
            printf("最小公共面積是:%d\n", minx * miny);
            printf("沒有符合要求的點的坐標(biāo)鲫尊。\n");
        }
    }
}

int divideGroup(int num[][2], int k, int group[])
{
    int groupnum = 0;
    int tx, ty;
    for (int i = 0; i < k; i++)
    {
        if (group[i] == -1) {
            group[i] = groupnum;
            
            tx = num[i][0];
            ty = num[i][1];
            for (int j = i + 1; j < k; j++) {
                if (group[j] == -1 && num[j][0] > tx && num[j][1] > ty) {
                    group[j] = groupnum;
                    tx = num[j][0];
                    ty = num[j][1];
                }
            }
            groupnum++;;
        }
    }
    return groupnum;
}

2013年上機題

題目

??二進(jìn)制數(shù)據(jù)文件1.bin中存放了100000個樣本點痴柔,每個樣本點由4個屬性構(gòu)成,屬性均為整型疫向。
??定義: 如a點的k個屬性不比b點的對應(yīng)屬性差(屬性值越小越好)咳蔚,
??且a點至少有一個屬性比b點的對應(yīng)屬性好,則稱a點k-支配b點搔驼。
??要求: 求出不被任何點k-支配的樣本點的個數(shù)谈火。
??在試卷上填寫求出的樣本點個數(shù)和所用時間(Elapsed Time)。

分析

??這道題看上去不難舌涨,但是倒是花費了我不少的時間糯耍,其中有許多大大小小的bug。先簡單介紹一下程序的幾個部分:
??(1)計時(這個已經(jīng)寫好了)
??(2)讀取文件中的數(shù)據(jù)并保存。
??(3)遍歷數(shù)組谍肤,尋找不被控制的數(shù)據(jù)啦租。
??我原來打算直接開一個$100000*4$的數(shù)組來保存數(shù)據(jù),但是報了stack overflow的錯荒揣,我查了下,說是棧的默認(rèn)大小是1M焊刹,這明顯超過了系任。我就決定用結(jié)構(gòu)體+手動分配內(nèi)存,但是沒想到保存結(jié)構(gòu)體指針的數(shù)組也超過了內(nèi)存限制(原諒我沒算)虐块。后來發(fā)現(xiàn)只要開成全局變量就好了俩滥。
??考慮到數(shù)據(jù)有100000個,昨天丁大佬說10000個數(shù)據(jù)的話復(fù)雜度為$n2$就有些大了贺奠,我就考慮到能不能減少時間復(fù)雜度霜旧。著就想到了鏈表。最開始的構(gòu)想是兩層遍歷儡率,去掉被控制的點挂据。后來想到為了減少比較的次數(shù),可以設(shè)置標(biāo)志位儿普。既然說到了標(biāo)志位崎逃,就想到不如直接用鏈表刪掉被控制的點就好了。這個算法的時間復(fù)雜度我沒有求眉孩,但是最好情況是$O(n)$个绍,最壞情況是$O(n2)$。

代碼

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

#define MAXSIZE 100000

void run(void);

int main()
{
    LARGE_INTEGER m_nFreq;
    LARGE_INTEGER m_nBeginTime;
    LARGE_INTEGER m_nEndTime;

    QueryPerformanceFrequency(&m_nFreq);
    QueryPerformanceCounter(&m_nBeginTime);

    run();

    QueryPerformanceCounter(&m_nEndTime);
    printf("\nElapsed Time = %lf sec\n",(double)(m_nEndTime.QuadPart-m_nBeginTime.QuadPart)/m_nFreq.QuadPart);
    return 0;
}

struct Dot
{
    int pos[4];
    Dot * next;
};


int dataRead(FILE * fp, Dot * head);
void eraseControlDot(Dot * head, int * count);
void freeSpace(Dot * head);

void run(void)
{
    FILE * fp = fopen("1.bin", "rb");
    if (fp == NULL) {
        printf("FILE OPEN ERROR!\n");
        exit(0);
    }

    Dot * head = (Dot *)malloc(sizeof(Dot));
    head->next = NULL;

    int count = dataRead(fp, head);
    eraseControlDot(head, &count);
    printf("%d", count);
    
   freeSpace(head);
   
    fclose(fp);
}

int dataRead(FILE * fp, Dot * head)
{
    int count = 0;
    int a, b, c, d;
    Dot * node, *p = head;

    while (fread(&a, sizeof(int), 1, fp) && fread(&b, sizeof(int), 1, fp) && fread(&c, sizeof(int), 1, fp) &&
    fread(&d, sizeof(int), 1, fp ) && count < MAXSIZE) {
        node = (Dot *)malloc(sizeof(Dot));
        node->pos[0] = a;
        node->pos[1] = b;
        node->pos[2] = c;
        node->pos[3] = d;
        node->next = NULL;
        p->next = node;
        p = node;
        count++;
    }
    return count;
}

void eraseControlDot(Dot * head, int * count)
{
    Dot *p, *q, *current;
    if (*count > 0) {
        current = head->next;
        while(current != NULL) {
            q = head;
            p = head->next;
            while (p != NULL) {
                if (p->pos[0] >= current->pos[0] && p->pos[1] >= current->pos[1] && 
                p->pos[2] >= current->pos[2]&& p->pos[3] >= current->pos[3] 
                &&(p->pos[0] > current->pos[0] || p->pos[1] > current->pos[1] 
                || p->pos[2] > current->pos[2] || p->pos[3] > current->pos[3])) {
                    q->next = p->next;
                    free(p);
                    p = q->next;
                    *count = *count - 1;
                }
                else {
                    p = p->next;
                    q = q->next;
                }           
            }
            current = current->next;
        }
    }
}

void freeSpace(Dot * head)
{
    Dot *p, *q;
    p = head->next;
    q = head;
    while (p != NULL) {
        free(q);
        q = p;
        p = p->next;
    }
    free(p);
}

2014年上機題

題目

??input.bin中有10000組數(shù)據(jù)浪汪,每組數(shù)據(jù)有4個屬性巴柿,都為整型。定義鄰近點為擁有k個距離小于等于d的點的點死遭,$d=\sqrt{(b_1-a_1)*(b_1-a_1)+(b_2-a_2)*(b_2-a_2)+(b_3-a_3)*(b_3-a_3)+(b_4-a_4)*(b_4-a_4)}$;現(xiàn)定義k=10广恢,d=7500,顯示出符合點的編號及其各個屬性殃姓。

分析

??這道題就是兩次循環(huán)求解袁波,不難,但是數(shù)據(jù)量比較大蜗侈,時間比較長篷牌。

代碼

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

#define ARRAYSIZE 10000
#define _CRT_SECURE_NO_WARNINGS

struct Dot {
    int pos[4];
    int ngb;
    void initDot() {
        ngb = 0;
    }
}points[ARRAYSIZE];

int fileRead(FILE *fp);
void countNeighbour(int count, double distance);
void showResult(int count, int k);

void main()
{
    LARGE_INTEGER m_nFreq;
    LARGE_INTEGER m_nBeginTime;
    LARGE_INTEGER m_nEndTime;

    QueryPerformanceFrequency(&m_nFreq);
    QueryPerformanceCounter(&m_nBeginTime);

    FILE * fp = fopen("1.bin", "rb");
    if (fp == NULL) {
        printf("FILE OPEN ERROR!\n");
        exit(1);
    }
    
    int k=10;
    double distance=7500;
    //printf("請輸入k和距離:");
    //scanf("%d%lf", &k, &distance);

    int count = fileRead(fp);
    countNeighbour(count, distance);
    showResult(count, k);

    fclose(fp);

    QueryPerformanceCounter(&m_nEndTime);
    printf("\nElapsed Time=%lf sec\n",(double)(m_nEndTime.QuadPart-m_nBeginTime.QuadPart)/m_nFreq.QuadPart);
}

int fileRead(FILE *fp)
{
    int num[4];
    int count = 0;
    while (fread(num, sizeof(int), 4, fp) && count < ARRAYSIZE) {
        points[count].initDot();
        for (int i = 0; i < 4; i++) {
            points[count].pos[i] = num[i];
        }
        count++;
    }
    return count;
}

void countNeighbour(int count, double distance)
{
    for (int i = 0; i < count - 1; i++) {
        for (int j = i + 1; j < count; j++) {
            if (sqrt((double)((points[i].pos[0]-points[j].pos[0])*(points[i].pos[0]-points[j].pos[0])
            +(points[i].pos[1] - points[j].pos[1])*(points[i].pos[1] - points[j].pos[1]) 
            +(points[i].pos[2] - points[j].pos[2])*(points[i].pos[2] - points[j].pos[2]) + 
            (points[i].pos[3] - points[j].pos[3])*(points[i].pos[3] - points[j].pos[3]))) < distance) 
        {
                points[i].ngb++;
                points[j].ngb++;
            }
        }
    }
}

void showResult(int count, int k)
{
    bool flag = true;
    for (int i = 0; i < count; i++) {
        if (points[i].ngb == k) {
            printf("第%d個點:(%d,%d,%d,%d)\n",i,points[i].pos[0], points[i].pos[1], points[i].pos[2], 
            points[i].pos[3]);
            flag = false;
        }
    }
    if (flag) {
        printf("沒有符合要求的點。\n");
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末踏幻,一起剝皮案震驚了整個濱河市枷颊,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖夭苗,帶你破解...
    沈念sama閱讀 218,607評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件信卡,死亡現(xiàn)場離奇詭異,居然都是意外死亡题造,警方通過查閱死者的電腦和手機傍菇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,239評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來界赔,“玉大人丢习,你說我怎么就攤上這事』吹浚” “怎么了咐低?”我有些...
    開封第一講書人閱讀 164,960評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長袜腥。 經(jīng)常有香客問我见擦,道長,這世上最難降的妖魔是什么羹令? 我笑而不...
    開封第一講書人閱讀 58,750評論 1 294
  • 正文 為了忘掉前任鲤屡,我火速辦了婚禮,結(jié)果婚禮上特恬,老公的妹妹穿的比我還像新娘执俩。我一直安慰自己,他們只是感情好癌刽,可當(dāng)我...
    茶點故事閱讀 67,764評論 6 392
  • 文/花漫 我一把揭開白布役首。 她就那樣靜靜地躺著,像睡著了一般显拜。 火紅的嫁衣襯著肌膚如雪衡奥。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,604評論 1 305
  • 那天远荠,我揣著相機與錄音矮固,去河邊找鬼。 笑死譬淳,一個胖子當(dāng)著我的面吹牛档址,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播邻梆,決...
    沈念sama閱讀 40,347評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼守伸,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了浦妄?” 一聲冷哼從身側(cè)響起尼摹,我...
    開封第一講書人閱讀 39,253評論 0 276
  • 序言:老撾萬榮一對情侶失蹤见芹,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后蠢涝,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體玄呛,經(jīng)...
    沈念sama閱讀 45,702評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,893評論 3 336
  • 正文 我和宋清朗相戀三年和二,在試婚紗的時候發(fā)現(xiàn)自己被綠了徘铝。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,015評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡儿咱,死狀恐怖庭砍,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情混埠,我是刑警寧澤,帶...
    沈念sama閱讀 35,734評論 5 346
  • 正文 年R本政府宣布诗轻,位于F島的核電站钳宪,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏扳炬。R本人自食惡果不足惜吏颖,卻給世界環(huán)境...
    茶點故事閱讀 41,352評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望恨樟。 院中可真熱鬧半醉,春花似錦、人聲如沸劝术。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,934評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽养晋。三九已至衬吆,卻和暖如春绳泉,著一層夾襖步出監(jiān)牢的瞬間零酪,已是汗流浹背孝凌。 一陣腳步聲響...
    開封第一講書人閱讀 33,052評論 1 270
  • 我被黑心中介騙來泰國打工峻呛, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人牙勘。 一個月前我還...
    沈念sama閱讀 48,216評論 3 371
  • 正文 我出身青樓方面,卻偏偏與公主長得像,于是被迫代替她去往敵國和親横腿。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,969評論 2 355

推薦閱讀更多精彩內(nèi)容