2010-1091
从 Trac 迁移的文章
这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。
原文章内容如下:
题目大意:寻找丢失的袜子,告知2*n-1只袜子的名字(保证名字长度为7),名字一样的可以计作一双,这样最后只需要找出多出的那只袜子(也就是丢失袜子的另外一只了),输出这只袜子的名字。[[BR]]
这里列举了三种不同的方法:法1最快且编程复杂度最小,其次法2,再次法3。[[BR]]
法1:位运算,利用异或操作,凡是偶数袜子的异或操作没有影响,而奇数袜子则记录下来,所以方法很不错的说,即快又省[[BR]]
法2:算是异或运算的手写版吧,统计名字每位各个字母出现的次数,出现奇数次的那个字母必定是此为上的答案。[[BR]]
法3:最模拟的办法,(直接读入近600000个名字,排序后遍历一次即可找出出现奇数次的名字,但是排序string的名字超时)把长为7的字符串看作26进制数,转换为数字(要long long)存储,再排序,排序后遍历找出现奇数次的数字,再转换为字符串输出,这个方法不推荐,又慢,又占空间。
{{{
#!cpp
#include<cstdio>
char t[10],f[10];
int main()
{
int j,k,i,n;
while(scanf("%d",&n)!=EOF)
{
scanf("%s",f);
for (j=2;j<=2*n-1;++j)
{
scanf("%s",t);
for (k=0;k<7;++k) f[k]^=t[k];
}
printf("%s\n",f);
}
return 0;
}
}}}
{{{
#!cpp
#include<cstdio>
#include<cstring>
int main()
{
int f[8][27];
int n,j,k,i;
char t[10];
while(scanf("%d",&n)!=EOF)
{
memset(f,0,sizeof(f));
for (j=1;j<=2*n-1;++j)
{
scanf("%s",t);
for (k=0;k<7;++k) f[k][t[k]-'a']++;
}
for (j=0;j<7;++j)
for (k=0;k<26;++k)
if (f[j][k]%2==1)
{
printf("%c",k+'a');
break;
}
printf("\n");
}
return 0;
}
}}}
{{{
#!cpp
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
long long f[600001];
int main()
{
long n,ans,j,k,i;
long long cc;
char t[10];
while(scanf("%ld",&n)!=EOF)
{
for (j=1;j<=2*n-1;++j)
{
scanf("%s",t);
cc=1;
f[j]=0;
for (k=0;k<7;++k)
{
f[j]+= (t[k]-'a')*cc;
cc=cc*26LL;
}
}
sort(f+1,f+2*n);
f[2*n]=-1;
i=1;
j=1;
while(j<=2*n-1)
{
while(f[j]==f[i]) ++j;
k=j-i;
if (k%2!=0) break;
i=j;
}
cc=f[i];
i=0;
while(cc!=0LL)
{
printf("%c",cc%26+'a');
cc=cc/26LL;
++i;
}
for (j=i;j<=6;++j) printf("a");
printf("\n");
}
return 0;
}
}}}
------------------------------------------------------------------------------------
题目大意:寻找丢失的袜子,告知2*n-1只袜子的名字(保证名字长度为7),名字一样的可以计作一双,这样最后只需要找出多出的那只袜子(也就是丢失袜子的另外一只了),输出这只袜子的名字。
这里列举了三种不同的方法:法1最快且编程复杂度最小,其次法2,再次法3。
法1:位运算,利用异或操作,凡是偶数袜子的异或操作没有影响,而奇数袜子则记录下来,所以方法很不错的说,即快又省
法2:算是异或运算的手写版吧,统计名字每位各个字母出现的次数,出现奇数次的那个字母必定是此为上的答案。
法3:最模拟的办法,(直接读入近600000个名字,排序后遍历一次即可找出出现奇数次的名字,但是排序string的名字超时)把长为7的字符串看作26进制数,转换为数字(要long long)存储,再排序,排序后遍历找出现奇数次的数字,再转换为字符串输出,这个方法不推荐,又慢,又占空间。
#include<cstdio>
char t[10],f[10];
int main()
{
int j,k,i,n;
while(scanf("%d",&n)!=EOF)
{
scanf("%s",f);
for (j=2;j<=2*n-1;++j)
{
scanf("%s",t);
for (k=0;k<7;++k) f[k]^=t[k];
}
printf("%s\n",f);
}
return 0;
}
#include<cstdio>
#include<cstring>
int main()
{
int f[8][27];
int n,j,k,i;
char t[10];
while(scanf("%d",&n)!=EOF)
{
memset(f,0,sizeof(f));
for (j=1;j<=2*n-1;++j)
{
scanf("%s",t);
for (k=0;k<7;++k) f[k][t[k]-'a']++;
}
for (j=0;j<7;++j)
for (k=0;k<26;++k)
if (f[j][k]%2==1)
{
printf("%c",k+'a');
break;
}
printf("\n");
}
return 0;
}
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
long long f[600001];
int main()
{
long n,ans,j,k,i;
long long cc;
char t[10];
while(scanf("%ld",&n)!=EOF)
{
for (j=1;j<=2*n-1;++j)
{
scanf("%s",t);
cc=1;
f[j]=0;
for (k=0;k<7;++k)
{
f[j]+= (t[k]-'a')*cc;
cc=cc*26LL;
}
}
sort(f+1,f+2*n);
f[2*n]=-1;
i=1;
j=1;
while(j<=2*n-1)
{
while(f[j]==f[i]) ++j;
k=j-i;
if (k%2!=0) break;
i=j;
}
cc=f[i];
i=0;
while(cc!=0LL)
{
printf("%c",cc%26+'a');
cc=cc/26LL;
++i;
}
for (j=i;j<=6;++j) printf("a");
printf("\n");
}
return 0;
}