Beyond the Void
BYVoid
USACO 3.1.5 Contact 聯繫
本文正體字版由OpenCC轉換

經典的位運算解題,邊讀入邊計算。 設置極限掩碼爲limit=(1«(B))-1; //2的B此次方-1 每讀入一個二進制數0或1,令unsigned int數字串str=((str«1)+c) & limit; 然後掃描str,從末尾向前掃描i=(A到B)位,把所得的數字串t最高位添加1,以區別有前導0的串,例如001和01,添加後變爲1001和101

mask=(1<<i)-1;
mask2=mask+1;
t=(S & mask) | mask2;

用哈希表記錄t的頻率 hash[t]++;

最後再排序按格式輸出即可,一定要小心,我格式錯了好幾次。

/*
ID: cmykrgb1
PROG: contact
LANG: C++
*/
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
	long value,cnt;
} bins;
FILE *fi,*fo;
long A,B,n;
unsigned int limit;
long hash[10000];
long cnt=0;
bins R[10000];

void print_bin(unsigned int t)
{
	int tmp[13],cnt=0;
	do{
		tmp[++cnt]=(t & 1)+48;
		t>>=1;
	}while (t);
	for (int i=cnt-1;i>=1;i--) putc(tmp[i],fo);
}

void vote(unsigned int S,int cy)
{
	int i;
	unsigned int mask,mask2,t;
	for (i=A;i<=B && i<=cy;i++)
	{
		mask=(1<<(i))-1;mask2=mask+1;
		t=(S & mask) | mask2;
		hash[t]++;
	}
}

void count()
{
	char c;	unsigned int str=0,cy=0;
	fi=fopen("contact.in","r");
	fo=fopen("contact.out","w");
	fscanf(fi,"%ld%ld%ldn",&A,&B,&n);
	limit=(1<<(B))-1; //2的B此次方-1
	while ((c=getc(fi))!=EOF)
		if (c!=10 && c!=13)
		{
			cy++;c-=48;
			str=((str<<1)+c) & limit;
			vote(str,cy);
		}
}

int cmp ( const void *a , const void *b ) 
{
	bins ta=(*(bins *)a),tb=(*(bins *)b);
	if (ta.cnt>tb.cnt) return -1;
	else if (ta.cnt<tb.cnt) return 1;
	else if (ta.cnt==tb.cnt)
	if (ta.value<tb.value) return -1;
	else return 1;
}

void print()
{
	unsigned int lt=(1<<(B+1))-1;
	int i;
	int now=0,pc=0,linecnt=0;
	bool flag,first=true;
	for (i=0;i<=lt;i++)
		if (hash[i])
		{
			cnt++;R[cnt].value=i;
			R[cnt].cnt=hash[i];
		}
	qsort(R+1,cnt,sizeof(bins),cmp);

	for (i=1;i<=cnt;i++)
	{
		if (R[i].cnt!=now)
		{
			now=R[i].cnt;
			if (pc==n) break;
			if (!first) fprintf(fo,"n");
			else first=false;
			fprintf(fo,"%ldn",now);
			pc++;linecnt=0;
		}
		else
		{
			linecnt++;
			if (linecnt==6)
			{
				putc('n',fo);linecnt=0;
			}
			elsefprintf(fo," ");
		}
		print_bin(R[i].value);
	}
	putc('n',fo);
	fclose(fi);
	fclose(fo);
}

int main()
{
	count();
	print();
	return 0;
}

上次修改時間 2017-02-03

相關日誌