青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

A Za, A Za, Fighting...

堅(jiān)信:勤能補(bǔ)拙

求平面最近點(diǎn)對(duì)的核心思想乃是二分,用遞歸實(shí)現(xiàn)。具體操作如下:

     若點(diǎn)的個(gè)數(shù)很少(比如小于3或者小于5),就直接枚舉。

     如點(diǎn)的個(gè)數(shù)很多,按現(xiàn)將所有點(diǎn)按X排序,并按X坐標(biāo)平均的分成左右兩個(gè)部分(假設(shè)分割線為X=nx),分別求出兩邊的最短距離minl與minr并令ans=min(minl,minr)。

     求出左右兩邊的最小值之后,剩下的工作就是合并。易見(jiàn)若該點(diǎn)集存在點(diǎn)對(duì)(a,b)的最近距離小于ans,則a,b一定分別在x=nx的兩邊,切nx-a.x與nx-b.x的絕對(duì)值肯定小于ans。

     據(jù)此我們可以將點(diǎn)集中所有X值在(nx-ans,nx+ans)的點(diǎn)都選出來(lái),那么滿足條件的(a,b)肯定都在其中。

     易見(jiàn)若存在(a,b)兩點(diǎn)他們之間的距離小于ans,那么a.y-b.y的絕對(duì)值也肯定小于ans。

     綜上存在(a,b)兩點(diǎn)他們之間的距離小于ans那,(a,b)一定在一個(gè)長(zhǎng)為2*ans寬為ans的矩形之中。而 且這個(gè)矩形被X=nx平分成兩個(gè)ans*ans的矩形,由于無(wú)論是在左邊還是在右邊,任意兩點(diǎn)的之間的距離總是小于等于ans的,所以兩個(gè)ans*ans 的矩形中最多只有4個(gè)點(diǎn)(分別在四個(gè)頂點(diǎn)上),長(zhǎng)為2*ans寬為ans的矩形最多有8個(gè)點(diǎn)。

     據(jù)此我們將所有X值在(nx-ans,nx+ans)的點(diǎn)按他們的Y值進(jìn)行排序。依次看每個(gè)點(diǎn)與它之后的7個(gè)點(diǎn)的距離是否小于ans,若小于則更新ans,最后求出來(lái)的結(jié)果就是平面最近點(diǎn)對(duì)的距離。保留產(chǎn)生該距離的兩個(gè)點(diǎn)即可得到最近點(diǎn)對(duì)。

     練手題目:Pku2107,Vijos1012

附C++代碼(Pku2107):

#include <iostream>
#include <cmath>

const long maxsize = 100000;

typedef struct 

double x, y; 
} PointType;

long list[maxsize], listlen,n;
PointType point[maxsize];

int sortcmp(const void *,const void *); 
double dis(PointType,PointType);
double getmin(double,double);
int listcmp(const void *,const void *); 
double shortest(long,long);
int init(void);

int main() 

while (init())
   printf("%.2lf\n",shortest(0, n - 1)/2);    
return 0;
}

int sortcmp(const void *a, const void *b) 

if (((PointType*)a)->x < ((PointType*)b)->x)    
   return -1;   
else 
   return 1; 
}

double dis(PointType a, PointType b) 

return sqrt((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y)); 
}

double getmin(double a, double b) 

return a<b?a:b;
}

int listcmp(const void *a, const void *b) 

if (point[*(int*)a].y < point[*(int*)b].y)    
   return -1;   
else 
   return 1; 
}

double shortest(long l, long r) 

if (r - l == 1) 
   return dis(point[l], point[r]);   
if (r - l == 2)    
   return getmin(getmin(dis(point[l], point[l+1]), dis(point[l], point[r])), dis(point[l+1], point[r]));   
long i, j, mid = (l + r) >> 1;   
double curmin = getmin(shortest(l, mid), shortest(mid + 1, r));   
listlen = 0;   
for (i = mid; i >= l && point[mid+1].x - point[i].x <= curmin; i --)    
   list[listlen++] = i;   
for (i = mid + 1; i <= r && point[i].x - point[mid].x <= curmin; i ++)    
   list[listlen++] = i;   
qsort(list, listlen, sizeof(list[0]), listcmp);   
for (i = 0; i < listlen; i ++)    
   for (j = i + 1; j < listlen && point[list[j]].y - point[list[i]].y <= curmin; j ++)     
    curmin = getmin(curmin, dis(point[list[i]], point[list[j]]));   
return curmin; 
}

int init(void)
{
int i;
scanf("%d", &n);      
for (i=0;i<n;i++) 
   scanf("%lf%lf",&point[i].x,&point[i].y);      
qsort(point,n,sizeof(point[0]),sortcmp);
return n;
}


自己寫(xiě)的代碼:

/*
 * Problem(classic):
 *    there're many points in a plane surface, find the nearest two points
 *    see: <CLRS> 33.4 section
 
*/
#include
<stdio.h>
#include
<stdlib.h>
#include
<string.h>
#include
<math.h>
#define INF 0x7FFFFFFF
#define NUM_MAX 100000
#define THRESHOLD 3

struct Point {
    
double x, y;
};
struct Point points[NUM_MAX];
int total, yindex[NUM_MAX];

double
min(
double arg1, double arg2)
{
    
return (arg1 <= arg2 ? arg1 : arg2);
}

double
distance(
struct Point *arg1, struct Point *arg2)
{
    
double x_diff = arg1->- arg2->x;
    
double y_diff = arg1->- arg2->y;
    
return sqrt(x_diff*x_diff + y_diff*y_diff);
}

int
compare_x(
const void *arg1, const void *arg2)
{
    
struct Point *p1 = (struct Point *)arg1;
    
struct Point *p2 = (struct Point *)arg2;
    
return (p1->- p2->x);
}

int
compare_y(
const void *arg1, const void *arg2)
{
    
struct Point *p1 = points + *(int *)arg1;
    
struct Point *p2 = points + *(int *)arg2;
    
return (p1->- p2->y);
}

void
init_preprocess()
{
    
int i;
    scanf(
"%d"&total);
    
for(i=0; i<total; ++i)
        scanf(
"%lf %lf"&points[i].x, &points[i].y);
    qsort(points, total, 
sizeof(struct Point), compare_x);
}

double
find_nearest(
int begin, int end)
{
    
int i, j;
    
double ret = INF;
    
if(end-begin+1 <= THRESHOLD) {
        
for(i=begin; i<end; ++i) {
            
for(j=i+1; j<=end; ++j)
                ret 
= min(ret, distance(points+i, points+j));
        }
        
return ret;
    }
    
int mid = begin + ((end - begin) >> 1);
    
double dis = min(find_nearest(begin, mid), find_nearest(mid+1, end));
    
int len = 0;
    
for(j=mid; j>=begin && points[mid+1].x-points[j].x<=dis; --j)
        yindex[len
++= j;
    
for(j=mid+1; j<=end && points[j].x-points[mid].x<=dis; ++j)
        yindex[len
++= j;
    qsort(yindex, len, 
sizeof(int), compare_y);
    ret 
= dis;
    
for(i=0; i<=len-7++i) {
        
for(j=i+1; j<=i+7++j)
            ret 
= min(ret, distance(points+yindex[i], points+yindex[j]));
    }
    
return ret;
}

double
brute_force(
int begin, int end)
{
    
double ret = INF;
    
int i, j;
    
for(i=begin; i<end; ++i) {
        
for(j=i+1; j<=end; ++j)
            ret 
= min(ret, distance(points+i, points+j));
    }
    
return ret;
}

int
main(
int argc, char **argv)
{
    init_preprocess();
    
double ret = find_nearest(0, total-1);
    printf(
"\nNearest Distance[Brute Force]: %f\n", brute_force(0, total-1));
    printf(
"\nNearest Distance: %f\n", ret);
}


posted @ 2011-09-03 23:17 simplyzhao 閱讀(1181) | 評(píng)論 (1)編輯 收藏
 在socket網(wǎng)絡(luò)程序中,TCP和UDP分別是面向連接和非面向連接的。因此TCP的socket編程,收發(fā)兩端(客戶端和服務(wù)器端)都要有一一成對(duì)的socket,因此,發(fā)送端為了將多個(gè)發(fā)往接收端的包,更有效的發(fā)到對(duì)方,使用了優(yōu)化方法(Nagle算法),將多次間隔較小且數(shù)據(jù)量小的數(shù)據(jù),合并成一個(gè)大的數(shù)據(jù)塊,然后進(jìn)行封包。這樣,接收端,就難于分辨出來(lái)了,必須提供科學(xué)的拆包機(jī)制。
       對(duì)于UDP,不會(huì)使用塊的合并優(yōu)化算法,這樣,實(shí)際上目前認(rèn)為,是由于UDP支持的是一對(duì)多的模式,所以接收端的skbuff(套接字緩沖區(qū))采用了鏈?zhǔn)浇Y(jié)構(gòu)來(lái)記錄每一個(gè)到達(dá)的UDP包,在每個(gè)UDP包中就有了消息頭(消息來(lái)源地址,端口等信息),這樣,對(duì)于接收端來(lái)說(shuō),就容易進(jìn)行區(qū)分處理了

保護(hù)消息邊界和流

那么什么是保護(hù)消息邊界和流呢?

       保護(hù)消息邊界,就是指?jìng)鬏攨f(xié)議把數(shù)據(jù)當(dāng)作一條獨(dú)立的消息在網(wǎng)上 
傳輸,接收端只能接收獨(dú)立的消息.也就是說(shuō)存在保護(hù)消息邊界,接收 
端一次只能接收發(fā)送端發(fā)出的一個(gè)數(shù)據(jù)包. 
       而面向流則是指無(wú)保護(hù)消息保護(hù)邊界的,如果發(fā)送端連續(xù)發(fā)送數(shù)據(jù), 
接收端有可能在一次接收動(dòng)作中,會(huì)接收兩個(gè)或者更多的數(shù)據(jù)包.

       我們舉個(gè)例子來(lái)說(shuō),例如,我們連續(xù)發(fā)送三個(gè)數(shù)據(jù)包,大小分別是2k, 
4k , 8k,這三個(gè)數(shù)據(jù)包,都已經(jīng)到達(dá)了接收端的網(wǎng)絡(luò)堆棧中,如果使 
UDP協(xié)議,不管我們使用多大的接收緩沖區(qū)去接收數(shù)據(jù),我們必須有 
三次接收動(dòng)作,才能夠把所有的數(shù)據(jù)包接收完.而使用TCP協(xié)議,我們 
只要把接收的緩沖區(qū)大小設(shè)置在14k以上,我們就能夠一次把所有的 
數(shù)據(jù)包接收下來(lái).只需要有一次接收動(dòng)作.

       這就是因?yàn)?strong style="line-height: 22px; color: black; background-color: #ffff66; ">UDP協(xié)議的保護(hù)消息邊界使得每一個(gè)消息都是獨(dú)立的.而 
流傳輸,卻把數(shù)據(jù)當(dāng)作一串?dāng)?shù)據(jù)流,他不認(rèn)為數(shù)據(jù)是一個(gè)一個(gè)的消息.

      所以有很多人在使用tcp協(xié)議通訊的時(shí)候,并不清楚tcp是基于流的 
傳輸,當(dāng)連續(xù)發(fā)送數(shù)據(jù)的時(shí)候,他們時(shí)常會(huì)認(rèn)識(shí)tcp會(huì)丟包.其實(shí)不然, 
因?yàn)楫?dāng)他們使用的緩沖區(qū)足夠大時(shí),他們有可能會(huì)一次接收到兩個(gè)甚 
至更多的數(shù)據(jù)包,而很多人往往會(huì)忽視這一點(diǎn),只解析檢查了第一個(gè) 
數(shù)據(jù)包,而已經(jīng)接收的其他數(shù)據(jù)包卻被忽略了.所以大家如果要作這 
類的網(wǎng)絡(luò)編程的時(shí)候,必須要注意這一點(diǎn).

結(jié)論:
     根據(jù)以上所說(shuō),可以這樣理解,TCP為了保證可靠傳輸,盡量減少額外
開(kāi)銷(每次發(fā)包都要驗(yàn)證),因此采用了流式傳輸,面向流的傳輸,
相對(duì)于面向消息的傳輸,可以減少發(fā)送包的數(shù)量。從而減少了額外開(kāi)
銷。但是,對(duì)于數(shù)據(jù)傳輸頻繁的程序來(lái)講,使用TCP可能會(huì)容易粘包。
當(dāng)然,對(duì)接收端的程序來(lái)講,如果機(jī)器負(fù)荷很重,也會(huì)在接收緩沖里
粘包。這樣,就需要接收端額外拆包,增加了工作量。因此,這個(gè)特
別適合的是數(shù)據(jù)要求可靠傳輸,但是不需要太頻繁傳輸?shù)膱?chǎng)合(
兩次操作間隔100ms,具體是由TCP等待發(fā)送間隔決定的,取決于內(nèi)核
中的socket的寫(xiě)法)

而UDP,由于面向的是消息傳輸,它把所有接收到的消息都掛接到緩沖
區(qū)的接受隊(duì)列中,因此,它對(duì)于數(shù)據(jù)的提取分離就更加方便,但是,
它沒(méi)有粘包機(jī)制,因此,當(dāng)發(fā)送數(shù)據(jù)量較小的時(shí)候,就會(huì)發(fā)生數(shù)據(jù)包
有效載荷較小的情況,也會(huì)增加多次發(fā)送的系統(tǒng)發(fā)送開(kāi)銷(系統(tǒng)調(diào)用,
寫(xiě)硬件等)和接收開(kāi)銷。因此,應(yīng)該最好設(shè)置一個(gè)比較合適的數(shù)據(jù)包
的包長(zhǎng),來(lái)進(jìn)行UDP數(shù)據(jù)的發(fā)送。(UDP最大載荷為1472,因此最好能
每次傳輸接近這個(gè)數(shù)的數(shù)據(jù)量,這特別適合于視頻,音頻等大塊數(shù)據(jù)
的發(fā)送,同時(shí),通過(guò)減少握手來(lái)保證流媒體的實(shí)時(shí)性)

來(lái)自: http://hi.baidu.com/chongerfeia/blog/item/b1e572f631dd7e28bd310965.html

TCP無(wú)保護(hù)消息邊界的解決
 針對(duì)這個(gè)問(wèn)題,一般有3種解決方案:

      (1)發(fā)送固定長(zhǎng)度的消息

      (2)把消息的尺寸與消息一塊發(fā)送

      (3)使用特殊標(biāo)記來(lái)區(qū)分消息間隔

     

下面我們主要分析下前兩種方法:

1、發(fā)送固定長(zhǎng)度的消息 
這種方法的好處是他非常容易,而且只要指定好消息的長(zhǎng)度,沒(méi)有遺漏未未發(fā)的數(shù)據(jù),我們重寫(xiě)了一個(gè)SendMessage方法。代碼如下:

  private static int SendMessage(Socket s, byte[] msg)

        { 
            int offset = 0; 
            int size = msg.Length; 
            int dataleft = size;

            while (dataleft > 0) 
            {

                int sent = s.Send(msg, offset, SocketFlags.None); 
                offset += sent; 
                dataleft -= sent;

            }

            return offset; 
        }

簡(jiǎn)要分析一下這個(gè)函數(shù):形參s是進(jìn)行通信的套接字,msg即待發(fā)送的字節(jié)數(shù)組。該方法使用while循環(huán)檢查是否還有數(shù)據(jù)未發(fā)送,尤其當(dāng)發(fā)送一個(gè)很龐大的數(shù)據(jù)包,在不能一次性發(fā)完的情況下作用比較明顯。特別的,用sent來(lái)記錄實(shí)際發(fā)送的數(shù)據(jù)量,和recv是異曲同工的作用,最后返回發(fā)送的實(shí)際數(shù)據(jù)總數(shù)。

   有sentMessage函數(shù)后,還要根據(jù)指定的消息長(zhǎng)度來(lái)設(shè)計(jì)一個(gè)新的Recive方法。代碼如下:

  private byte[] ReciveMessage(Socket s, int size) 
        {

            int offset = 0; 
            int recv; 
            int dataleft = size; 
            byte[] msg = new byte[size];


            while (dataleft > 0)

            {

                //接收消息 
                recv = s.Receive(msg, offset, dataleft, 0); 
                if (recv == 0)

                {

                    break;

                } 
                offset += recv; 
                dataleft -= recv;

            }

            return msg;

        }

以上這種做法比較適合于消息長(zhǎng)度不是很長(zhǎng)的情況。

2、消息長(zhǎng)度與消息一同發(fā)送

我們可以這樣做:通過(guò)使用消息的整形數(shù)值來(lái)表示消息的實(shí)際大小,所以要把整形數(shù)轉(zhuǎn)換為字節(jié)類型。下面是發(fā)送變長(zhǎng)消息的SendMessage方法。具體代碼如下:

  private static int SendMessage(Socket s, byte[] msg) 
        {

            int offset = 0; 
            int sent; 
            int size = msg.Length; 
            int dataleft = size; 
            byte[] msgsize = new byte[2];

            //將消息尺寸從整形轉(zhuǎn)換成可以發(fā)送的字節(jié)型 
            msgsize = BitConverter.GetBytes(size);


            //發(fā)送消息的長(zhǎng)度信息 
            sent = s.Send(size);

            while (dataleft > 0)

            {

                sent = s.Send(msg, offset, dataleft, SocketFlags.None);

                //設(shè)置偏移量

                offset += sent; 
                dataleft -= sent;

            }

            return offset;

        }


下面是接收變長(zhǎng)消息的ReciveVarMessage方法。代碼如下:

private byte[] ReciveVarMessage(Socket s) 
        {


            int offset = 0; 
            int recv; 
            byte[] msgsize = new byte[2];


            //將字節(jié)數(shù)組的消息長(zhǎng)度信息轉(zhuǎn)換為整形 
            int size = BitConverter.ToInt16(msgsize); 
            int dataleft = size; 
            byte[] msg = new byte[size];


            //接收2個(gè)字節(jié)大小的長(zhǎng)度信息 
            recv = s.Receive(msgsize, 0, 2, 0); 
            while (dataleft > 0) 
            {

                //接收數(shù)據(jù) 
                recv = s.Receive(msg, offset, dataleft, 0); 
                if (recv == 0) 
                { 
                    break; 
                } 
                offset += recv; 
                dataleft -= recv;

            }

            return msg;

        }

posted @ 2011-09-01 18:36 simplyzhao 閱讀(666) | 評(píng)論 (0)編輯 收藏
from: Programming Pearl

/* Copyright (C) 1999 Lucent Technologies */
/* From 'Programming Pearls' by Jon Bentley */

/* longdup.c -- Print longest string duplicated M times */

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

int pstrcmp(char **p, char **q)
{   
return strcmp(*p, *q); }

int comlen(char *p, char *q)
{    
int i = 0;
    
while (*&& (*p++ == *q++))
        i
++;
    
return i;
}

#define M 1
#define MAXN 5000000
char c[MAXN], *a[MAXN];

int main()
{   
int i, ch, n = 0, maxi, maxlen = -1;
    
while ((ch = getchar()) != EOF) {
        a[n] 
= &c[n];
        c[n
++= ch;
    }
    c[n] 
= 0;
    qsort(a, n, 
sizeof(char *), pstrcmp);
    
for (i = 0; i < n-M; i++)
        
if (comlen(a[i], a[i+M]) > maxlen) {
            maxlen 
= comlen(a[i], a[i+M]);
            maxi 
= i;
        }
    printf(
"%.*s\n", maxlen, a[maxi]);
    
return 0;
}
posted @ 2011-08-19 15:11 simplyzhao 閱讀(607) | 評(píng)論 (1)編輯 收藏
代碼1(STL的map版本)
#include<iostream>
#include
<map>
#include
<string>

using namespace std;

int
main(
int argc, char **argv)
{
    map
<stringint> M;
    map
<stringint>::iterator j;
    
string t;
    
while(cin>>t)
        M[t]
++;

    
for(j=M.begin(); j!=M.end(); ++j)
        cout
<<j->first<<"\t"<<j->second<<endl;

    
return 0;
}


代碼2(自己的Hash)
#include<stdio.h>
#include
<stdlib.h>
#include
<string.h>
#define WORD_BUF 128
#define NHASH 29989 /* prime number just bigger than needed */
#define MULT 31

struct HNode {
    
char *word;
    
int count;
    
struct HNode *next;
};
struct HNode *Hash[NHASH] = {NULL}; 

#define NODEGROUP 1000
struct HNode *nodebuf;
int nodeleft = 0;

struct HNode *
node_alloc()
{
    
if(nodeleft == 0) {
        nodebuf 
= (struct HNode *)malloc(NODEGROUP * sizeof(struct HNode));
        nodeleft 
= NODEGROUP;
    }
    
--nodeleft;
    
return (nodebuf++);
}

unsigned 
int
hash(
char *str) /* a simple implementation of string-hash, others like ELFHash */
{
    unsigned 
int ret = 0;
    
char *ptr;
    
for(ptr=str; *ptr; ++ptr)
        ret 
= ret * MULT + (*ptr);
    
return (ret % NHASH);
}

void
insert_hash(
char *word)
{
    
struct HNode *node;
    unsigned 
int h = hash(word);
    
for(node=Hash[h]; node!=NULL; node=node->next)
        
if(strcmp(node->word, word) == 0) {
            
++(node->count);
            
return;
        }
    
struct HNode *pend = node_alloc();
    pend
->word = strdup(word);
    pend
->count = 1;
    pend
->next = Hash[h];
    Hash[h] 
= pend;
}

int
main(
int argc, char **argv)
{
    
char buf[WORD_BUF];
    
while(scanf("%s", buf) != EOF) {
        insert_hash(buf);
    }

    
int i;
    
struct HNode *node;
    
for(i=0; i<NHASH; ++i) 
        
for(node=Hash[i]; node!=NULL; node=node->next) 
            printf(
"%s\t%d\n", node->word, node->count);

    
return 0;
}

posted @ 2011-08-19 14:37 simplyzhao 閱讀(594) | 評(píng)論 (0)編輯 收藏
代碼:

/* 問(wèn)題: 兩整數(shù)相除,求循環(huán)節(jié) */
/* 分析:
 * 模擬整數(shù)相除的步驟,記錄每次的商、余,當(dāng)余重復(fù)時(shí)即發(fā)現(xiàn)循環(huán)節(jié) 
 * 余的范圍為[0, 被除數(shù)),因此記錄數(shù)組的大小可根據(jù)被除數(shù)確定
 
*/
#include
<stdio.h>
#include
<stdlib.h>
#include
<string.h>

void
get_circle_digits(unsigned 
int a, unsigned int b)
{
    
int i, mod, tmp, index = 0;
    
int *div = (int *)malloc(sizeof(int* b);
    
int *mod_pos = (int *)malloc(sizeof(int* b);
    memset(mod_pos, 
-1sizeof(int)*b);
    mod 
= a = a%b;
    
while(1) {
        
if(mod==0 || mod_pos[mod]!=-1)
            
break;
        mod_pos[mod] 
= index;
        tmp 
= mod*10;
        div[index] 
= tmp / b;
        mod 
= tmp % b;
        
++index;
    }
    
if(mod == 0
        printf(
"No Circle\n");
    
else {
        printf(
"0.");
        
for(i=0; i<mod_pos[mod]; i++)
            printf(
"%d", div[i]);
        printf(
"(");
        
for(i=mod_pos[mod]; i<index; i++)
            printf(
"%d", div[i]);
        printf(
")");
        printf(
"\n");
    }
}

int
main(
int argc, char **argv)
{
    unsigned 
int a, b;
    
while(scanf("%u %u"&a, &b) != EOF) {
        get_circle_digits(a, b);
    }
    
return 0;
}
posted @ 2011-08-17 16:24 simplyzhao 閱讀(497) | 評(píng)論 (0)編輯 收藏
代碼:
#include<stdio.h>
#include
<stdlib.h>
#include
<string.h>
#define MAX_K 101
#define MAX_N 1001
char matrix[MAX_N][MAX_N];
char visited[MAX_N];
short count[MAX_N];
int pastures[MAX_K];

int K, N, M;

void
dfs(
int pasture)
{
    
int i;
    
++count[pasture];
    visited[pasture] 
= 1;
    
for(i=1; i<=N; ++i) {
        
if(matrix[pasture][i] && !visited[i])
            dfs(i);
    }
}

int
main(
int argc, char **argv)
{
    
int i, x, y, ret = 0;
    scanf(
"%d %d %d"&K, &N, &M);
    
for(i=1; i<=K; ++i)
        scanf(
"%d", pastures+i);
    
for(i=1; i<=M; ++i) {
        scanf(
"%d %d"&x, &y);
        matrix[x][y] 
= 1;
    }
    
    
for(i=1; i<=K; ++i) {
        memset(visited, 
0sizeof(visited));
        dfs(pastures[i]);
    }

    
for(i=1; i<=N; ++i)
        
if(count[i] == K)
            
++ret;
    printf(
"%d\n", ret);
}


Cow Picnic
Time Limit: 2000MSMemory Limit: 65536K
Total Submissions: 3878Accepted: 1576

Description

The cows are having a picnic! Each of Farmer John's K (1 ≤ K ≤ 100) cows is grazing in one of N (1 ≤ N ≤ 1,000) pastures, conveniently numbered 1...N. The pastures are connected by M (1 ≤ M ≤ 10,000) one-way paths (no path connects a pasture to itself).

The cows want to gather in the same pasture for their picnic, but (because of the one-way paths) some cows may only be able to get to some pastures. Help the cows out by figuring out how many pastures are reachable by all cows, and hence are possible picnic locations.

Input

Line 1: Three space-separated integers, respectively: KN, and M 
Lines 2..K+1: Line i+1 contains a single integer (1..N) which is the number of the pasture in which cow i is grazing. 
Lines K+2..M+K+1: Each line contains two space-separated integers, respectively A and B (both 1..N and A != B), representing a one-way path from pasture A to pasture B.

Output

Line 1: The single integer that is the number of pastures that are reachable by all cows via the one-way paths.

Sample Input

2 4 4
2
3
1 2
1 4
2 3
3 4

Sample Output

2

Hint

The cows can meet in pastures 3 or 4.

Source






posted @ 2011-08-15 16:13 simplyzhao 閱讀(217) | 評(píng)論 (0)編輯 收藏
代碼:
#include<stdio.h>
#include
<stdlib.h>
#include
<string.h>
#include
<limits.h>
#define MAX_NUM 26
char adj[MAX_NUM][MAX_NUM];
int num, ret, colors[MAX_NUM];

int
is_valid(
int depth, int color)
{
    
int i;
    
for(i=0; i<depth; ++i) {
        
if(adj[i][depth] && colors[i]==color)
            
return 0;
    }
    
return 1;
}

void
dfs(
int depth, int color_used)
{
    
if(color_used >= ret)
        
return;
    
if(depth >= num) {
        ret 
= color_used;
        
return;
    }

    
int i;
    
for(i=0; i<color_used; ++i) {
        
if(is_valid(depth, i)) {
            colors[depth] 
= i;
            dfs(depth
+1, color_used);
            colors[depth] 
= -1;
        }
    }    
    colors[depth] 
= color_used;
    dfs(depth
+1, color_used+1);
    colors[depth] 
= -1;
}

int
main(
int argc, char **argv)
{
    
int i;
    
char info[MAX_NUM+2], *ptr;

    
while(scanf("%d"&num)!=EOF && num) {
        ret 
= INT_MAX;
        memset(colors, 
-1sizeof(colors));
        memset(adj, 
0sizeof(adj));
        
for(i=0; i<num; ++i) {
            scanf(
"%s", info);
            ptr 
= info+2;
            
while(*ptr != '\0') {
                adj[i][(
*ptr)-'A'= 1;
                
++ptr;
            }
        }
        dfs(
00);
        printf(
"%d %s needed.\n", ret, ret<=1?"channel":"channels");
    }
}

Channel Allocation
Time Limit: 1000MSMemory Limit: 10000K
Total Submissions: 8353Accepted: 4248

Description

When a radio station is broadcasting over a very large area, repeaters are used to retransmit the signal so that every receiver has a strong signal. However, the channels used by each repeater must be carefully chosen so that nearby repeaters do not interfere with one another. This condition is satisfied if adjacent repeaters use different channels. 

Since the radio frequency spectrum is a precious resource, the number of channels required by a given network of repeaters should be minimised. You have to write a program that reads in a description of a repeater network and determines the minimum number of channels required.

Input

The input consists of a number of maps of repeater networks. Each map begins with a line containing the number of repeaters. This is between 1 and 26, and the repeaters are referred to by consecutive upper-case letters of the alphabet starting with A. For example, ten repeaters would have the names A,B,C,...,I and J. A network with zero repeaters indicates the end of input. 

Following the number of repeaters is a list of adjacency relationships. Each line has the form: 

A:BCDH 

which indicates that the repeaters B, C, D and H are adjacent to the repeater A. The first line describes those adjacent to repeater A, the second those adjacent to B, and so on for all of the repeaters. If a repeater is not adjacent to any other, its line has the form 

A: 

The repeaters are listed in alphabetical order. 

Note that the adjacency is a symmetric relationship; if A is adjacent to B, then B is necessarily adjacent to A. Also, since the repeaters lie in a plane, the graph formed by connecting adjacent repeaters does not have any line segments that cross. 

Output

For each map (except the final one with no repeaters), print a line containing the minumum number of channels needed so that no adjacent channels interfere. The sample output shows the format of this line. Take care that channels is in the singular form when only one channel is required.

Sample Input

2
A:
B:
4
A:BC
B:ACD
C:ABD
D:BC
4
A:BCD
B:ACD
C:ABD
D:ABC
0

Sample Output

1 channel needed.
3 channels needed.
4 channels needed. 

Source



posted @ 2011-08-14 10:32 simplyzhao 閱讀(298) | 評(píng)論 (0)編輯 收藏
代碼:
#include<stdio.h>
#include
<stdlib.h>
#include
<string.h>
#define MAX_NUM 100
#define VALID(x, y) ((x)>=0 && (x)<m && (y)>=0 && (y)<n)
int m, n, count;
char grid[MAX_NUM][MAX_NUM+1];
char visited[MAX_NUM][MAX_NUM+1];

const int dx[] = {-1-1-100111};
const int dy[] = {-101-11-101};
void
dfs_inner(
int x, int y)
{
    
int i, next_x, next_y;
    visited[x][y] 
= 1;
    
for(i=0; i<8++i) {
        next_x 
= x + dx[i];
        next_y 
= y + dy[i];
        
if(VALID(next_x, next_y) && !visited[next_x][next_y] &&
                grid[next_x][next_y]
=='@')
            dfs_inner(next_x, next_y);
    }
}

void
dfs()
{
    
int i, j;
    
for(i=0; i<m; ++i)
        
for(j=0; j<n; ++j)
            
if(!visited[i][j] && grid[i][j]=='@') {
                
++count;
                dfs_inner(i, j);
            }
}

int
main(
int argc, char **argv)
{
    
int i;
    
while(scanf("%d %d"&m, &n)!= EOF && m) {
        count 
= 0;
        memset(visited, 
0sizeof(visited));
        
for(i=0; i<m; ++i)
            scanf(
"%s", grid[i]);
        dfs();
        printf(
"%d\n", count);
    }
}

Oil Deposits
Time Limit: 1000MSMemory Limit: 10000K
Total Submissions: 7595Accepted: 4267

Description

The GeoSurvComp geologic survey company is responsible for detecting underground oil deposits. GeoSurvComp works with one large rectangular region of land at a time, and creates a grid that divides the land into numerous square plots. It then analyzes each plot separately, using sensing equipment to determine whether or not the plot contains oil. A plot containing oil is called a pocket. If two pockets are adjacent, then they are part of the same oil deposit. Oil deposits can be quite large and may contain numerous pockets. Your job is to determine how many different oil deposits are contained in a grid.

Input

The input contains one or more grids. Each grid begins with a line containing m and n, the number of rows and columns in the grid, separated by a single space. If m = 0 it signals the end of the input; otherwise 1 <= m <= 100 and 1 <= n <= 100. Following this are m lines of n characters each (not counting the end-of-line characters). Each character corresponds to one plot, and is either `*', representing the absence of oil, or `@', representing an oil pocket. 

Output

are adjacent horizontally, vertically, or diagonally. An oil deposit will not contain more than 100 pockets.

Sample Input

1 1 * 3 5 *@*@* **@** *@*@* 1 8 @@****@* 5 5  ****@ *@@*@ *@**@ @@@*@ @@**@ 0 0

Sample Output

0 1 2 2 

Source

Mid-Central USA 1997

posted @ 2011-08-14 10:29 simplyzhao 閱讀(341) | 評(píng)論 (0)編輯 收藏
     摘要: 題目:
給你一個(gè)3升的杯子和一個(gè)5升的(杯子是沒(méi)有刻度的),要你取4升水來(lái)(水可以無(wú)限取),請(qǐng)問(wèn)該如何操作。
泛化:
給你一個(gè)m升的杯子和一個(gè)n升的(杯子是沒(méi)有刻度的),要你取target升水來(lái)(水可以無(wú)限取),請(qǐng)問(wèn)該如何操作.

思路:
搜索: BFS or DFS  閱讀全文
posted @ 2011-08-12 17:40 simplyzhao 閱讀(215) | 評(píng)論 (0)編輯 收藏
前提: 已排序
時(shí)間復(fù)雜度: O(logN)
例如: 找出某個(gè)target出現(xiàn)的位置(隨機(jī)),某個(gè)target第一次出現(xiàn)的位置,某個(gè)target最后一次出現(xiàn)的位置

問(wèn)題: 如果在未排序的數(shù)組中使用二分搜索,結(jié)果會(huì)怎么樣?

答: 如果二分搜索聲稱找到了target,那么該target就一定存在于數(shù)組中,
     但是,在應(yīng)用于未排序數(shù)組時(shí),算法有時(shí)會(huì)在target實(shí)際存在的情況下報(bào)告說(shuō)該target不存在

代碼:

int
vector_bsearch(
struct Vector *vector, const void *target, compare_func compare)
{
    
int lo, hi, mid, tmp;
    lo 
= 0;
    hi 
= (vector->count) - 1;
    
while(lo <= hi) {
        mid 
= lo + ((hi - lo) >> 1);
        tmp 
= compare(vector->array[mid], target);
        
if(tmp == 0)
            
return mid;
        
else if(tmp > 0)
            hi 
= mid - 1;
        
else
            lo 
= mid + 1;
    }
    
return -1;
}

int
vector_lower(
struct Vector *vector, const void *target, compare_func compare)
{
    
int lo, hi, mid;
    lo 
= -1;
    hi 
= vector->count;
    
/* distance between lo and hi at least larger than 1, which ensure mid won't equals to either lo or hi */
    
while(lo+1 != hi) { 
        
/* loop invariant: vector[lo]<target && vector[hi]>=target && lo<hi */
        mid 
= lo + ((hi - lo) >> 1);
        
if(compare(vector->array[mid], target) >= 0)
            hi 
= mid;
        
else 
            lo 
= mid;
    }
    
if(hi>=(vector->count) || compare(vector->array[hi], target)!=0)
        
return -1;
    
return hi;
}

int
vector_upper(
struct Vector *vector, const void *target, compare_func compare)
{
    
int lo, hi, mid;
    lo 
= -1;
    hi 
= vector->count;
    
/* distance between lo and hi at least larger than 1, which ensure mid won't equals to either lo or hi */
    
while(lo+1 != hi) {
        
/* loop invariant: vector[lo]<=target && vector[hi]>target && lo<hi */
        mid 
= lo + ((hi - lo) >> 1);
        
if(compare(vector->array[mid], target) <= 0)
            lo 
= mid;
        
else
            hi 
= mid;
    }
    
if(lo<0 || compare(vector->array[lo], target)!=0)
        
return -1;
    
return lo;
}









posted @ 2011-08-12 17:19 simplyzhao 閱讀(196) | 評(píng)論 (0)編輯 收藏
僅列出標(biāo)題
共21頁(yè): 1 2 3 4 5 6 7 8 9 Last 

導(dǎo)航

<2010年8月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
2930311234

統(tǒng)計(jì)

常用鏈接

留言簿(1)

隨筆分類

隨筆檔案

搜索

最新評(píng)論

閱讀排行榜

評(píng)論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美视频一区二| 国产噜噜噜噜噜久久久久久久久| 国精品一区二区三区| 香蕉久久久久久久av网站| 亚洲视频1区2区| 国产精品你懂的在线欣赏| 欧美在线地址| 久久成人18免费观看| 亚洲国产精品第一区二区三区| 欧美成人情趣视频| 欧美精品黄色| 久久www成人_看片免费不卡| 欧美综合国产| 亚洲精品专区| 亚洲天堂av图片| 国内自拍视频一区二区三区| 欧美承认网站| 国产精品a久久久久| 久久精品人人做人人综合| 久久久久国产精品一区| 亚洲乱码久久| 欧美一级在线视频| 亚洲精品久久久蜜桃| 亚洲小说春色综合另类电影| 狠狠色狠狠色综合日日小说| 亚洲人成久久| 国语精品一区| 夜夜狂射影院欧美极品| 狠狠v欧美v日韩v亚洲ⅴ| 亚洲精华国产欧美| 国产亚洲欧美一区二区三区| 亚洲精品免费网站| 狠狠入ady亚洲精品经典电影| 亚洲精品久久视频| 激情久久久久久| 宅男噜噜噜66一区二区| 亚洲国产精品ⅴa在线观看 | 在线播放中文字幕一区| 一个色综合导航| 亚洲第一页自拍| 午夜精品理论片| 亚洲最黄网站| 免费国产自线拍一欧美视频| 午夜视频在线观看一区| 欧美精选午夜久久久乱码6080| 久久精品免费| 国产精品福利在线观看| 亚洲国产mv| 国内精品久久久久影院薰衣草| 宅男精品视频| 中国亚洲黄色| 欧美日本精品| 亚洲电影在线| 亚洲激情另类| 久久综合中文字幕| 久久亚洲精品网站| 国产日韩欧美亚洲| 亚洲在线黄色| 久久不射中文字幕| 国产欧美欧美| 亚洲一区二区在线看| 午夜老司机精品| 国产精品日本精品| 亚洲一区二区三区精品动漫| 亚洲综合色在线| 国产精品久久久久99| 亚洲一区二区三区三| 亚洲欧美日韩综合| 国产精品腿扒开做爽爽爽挤奶网站| 99国产精品久久久久久久久久 | 国产精品国产成人国产三级| 日韩一区二区精品葵司在线| 99视频一区| 欧美三级视频在线| 亚洲一区黄色| 久久精品综合一区| 极品日韩av| 久久一区欧美| 亚洲激情在线观看| 亚洲深夜福利网站| 国产精品视频免费| 久久狠狠婷婷| 欧美成人精品一区| 99v久久综合狠狠综合久久| 欧美日韩ab| 亚洲欧美日韩综合| 蜜臀av在线播放一区二区三区| 在线国产日韩| 欧美日韩一区二区三区视频| 亚洲尤物精选| 欧美高清在线视频观看不卡| 99国产精品自拍| 国产毛片一区| 久久亚洲精品一区| av成人免费观看| 久久九九99视频| 亚洲精品三级| 国产精品少妇自拍| 久久亚洲综合色| 亚洲香蕉视频| 欧美国产在线视频| 亚洲欧美激情视频| 在线观看欧美黄色| 欧美日韩在线大尺度| 久久精品一区蜜桃臀影院| 亚洲精品一区二区三区婷婷月| 久久高清免费观看| 亚洲精品一区二区三区蜜桃久| 国产伦精品一区二区三| 麻豆av一区二区三区久久| 一区二区三区精品在线 | 一本久久a久久精品亚洲| 国产麻豆精品theporn| 蜜臀av在线播放一区二区三区| 一区二区三区日韩精品| 欧美第一黄色网| 久久精品2019中文字幕| 一级日韩一区在线观看| 1024国产精品| 国产一区二区三区日韩欧美| 欧美日韩成人| 欧美国产精品人人做人人爱| 欧美一区午夜精品| 亚洲一二三区在线| 亚洲九九爱视频| 欧美激情一区二区| 久久夜色精品| 欧美在现视频| 欧美视频亚洲视频| 欧美成年人视频网站| 久久精品色图| 午夜精品网站| 亚洲女ⅴideoshd黑人| 亚洲视频axxx| 99精品视频免费全部在线| 亚洲黄色影院| 亚洲狠狠丁香婷婷综合久久久| 蜜桃av一区二区在线观看| 久久久国产精彩视频美女艺术照福利| 午夜精品www| 亚洲欧美一区二区三区久久 | 国产日韩欧美自拍| 国产精品久久久久久久久| 欧美日韩一区三区四区| 欧美伦理一区二区| 欧美黄网免费在线观看| 欧美激情免费在线| 欧美日本久久| 欧美日韩国产综合视频在线观看中文 | 欧美日韩高清不卡| 欧美日韩国产区一| 欧美日韩国产成人在线观看| 欧美破处大片在线视频| 欧美人与禽猛交乱配视频| 欧美精品三区| 国产精品国产三级国产普通话99| 欧美日韩另类视频| 国产精品国产三级国产专区53| 国产精品h在线观看| 国产精品一区免费视频| 国产亚洲福利| 精品动漫一区| 日韩视频一区二区三区| 亚洲一区二区三区免费在线观看| 亚洲在线免费视频| 欧美伊人影院| 欧美顶级艳妇交换群宴| 亚洲精品在线电影| 亚洲男人的天堂在线| 久久久精品免费视频| 欧美黄色小视频| 国产精品永久| 1024国产精品| 亚洲一二三四久久| 久久夜色精品亚洲噜噜国产mv| 亚洲大胆视频| 亚洲一区二区三区乱码aⅴ| 久久国产精品亚洲77777| 欧美xx视频| 国产精品揄拍一区二区| 亚洲国产精品嫩草影院| 亚洲自拍啪啪| 欧美成人免费网站| 中日韩男男gay无套| 久久频这里精品99香蕉| 欧美视频一区二区三区| 黄色成人免费网站| 亚洲天堂视频在线观看| 久久夜色精品国产| 99视频精品全国免费| 久久精品国产久精国产爱| 欧美日韩成人在线视频| 狠狠色丁香久久婷婷综合丁香| 中国成人在线视频| 欧美a级大片| 亚洲欧美一区二区精品久久久| 欧美黄在线观看| 在线成人激情黄色| 午夜视频在线观看一区二区| 亚洲欧洲一区二区在线播放 |