今天写了部分补题。
A题以后记不住了再补,这次比赛还差一个splay树。
真的以后不能看题解了,不然写过的题和没写有什么区别。
发现自己特别羡慕那种在比赛的时候无论发生什么都淡定的人,啊,发生别的事冷静的人也是。特别佩服这一类人。
但是我也知道,我可能永远都无法成为这种人。
J
题目描述
变位词是指改变某个词的字母顺序后构成的新词。蔡老板最近沉迷研究变位词并给你扔了一道题:
给你一些单词,让你把里面的变位词分组找出来。互为变位词的归为一组,最后输出含有变位词最多的前五组。如果有组数相同的按照字典序输出。
输入
输入包含由小写字母组成的单词,用换行分割,被EOF终止。 输入数据不超过30000个单词。
输出
输出五组包含单词数量最多的变位词,如果少于五组,输出全部。对每组输出,写出它的大小和成员词,成员词按字典序排序用空格分隔,每组输出之间用换行分隔,相同词只输出一次,但算个数。
样例输入
neuq
tea
bate
beat
caret
trace
nueq
carte
cater
crate
abet
ate
eat
beta
eta
signal
样例输出
Group of size 5: caret carte cater crate trace .
Group of size 4: abet bate beat beta .
Group of size 4: ate eat eta tea .
Group of size 2: neuq nueq .
Group of size 1: signal .
代码:
这是一份用stl硬怼的代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
using namespace std;
const int maxn = 100;
char s[maxn],d[maxn];
map<string,set<string> > data;
map<string, int> id;
struct node
{
char s[maxn];
int len,id;
node(){}
node(char a[maxn],int b)
{
int alen = strlen(a);
for(int i = 0; i <= alen; i++)
s[i] = a[i];
len = 1; id = b;
}
}dlen[30000+10];
bool cmp(node a,node b)
{
if(a.len == b.len)
{
if(strcmp(a.s,b.s) <= 0) return true;
else return false;
}
else return a.len > b.len;
}
int main()
{
//freopen("D://in.txt","r",stdin);
int num = 0;
while(~scanf("%s",s))
{
int slen = strlen(s);
for(int i = 0; i <= slen; i++)
d[i] = s[i];
sort(s,s+slen);
if(data.count(s))
{
data[s].insert(d);
if(strcmp(dlen[id[s]].s, d ) > 0)
{
for(int i = 0; i <= slen; i++)
dlen[id[s]].s[i] = d[i];
}
dlen[id[s] ].len++;
}
else
{
data[s].insert(d);
id[s] = num;
dlen[num] = node(d,num); num++;
}
}
sort(dlen, dlen + num, cmp);
for(int i = 0; i < min(5,num); i ++)
{
printf("Group of size %d: ",dlen[i].len);
int slen = strlen(dlen[i].s);
sort(dlen[i].s,dlen[i].s+slen);
set<string> :: iterator it = data[dlen[i].s].begin();
for(; it != data[dlen[i].s].end(); it++)
cout<<*it<<" ";
cout<<"."<<endl;
}
return 0;
}
题目描述
这是一个斐波那契数列:
f1 = 1
f2 = 2
fn = fn-1 + fn-2 (n>=3)
蔡老板想知道,给你两个数a、b,你能否求出在区间[a,b]里有多少个斐波那契数。
输入
多组数据输入。一行为一组输入数据,包括两个非负整数a、b(a <= b <= 10^100),当a=b=0时输入终止。
输出
对每组输入,输出单独一行,包含一个整数表示区间[a,b]里的斐波那契数个数。
样例输入
10 100
1234567890 9876543210
0 0
样例输出
5
4
思路:大数。会写加就行
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn = 1005;
struct Bigint
{
char d[maxn];
int len;
Bigint(){memset(d,'\0',maxn*sizeof(char));len = 0;}
Bigint(char data[maxn])
{
len = strlen(data);
for(int i = 0; i <= len; i++)
d[i] = data[i];
}
}fib[maxn];
Bigint operator+(Bigint a,Bigint b)
{
Bigint c;
int flag = 0;
int len = max(b.len, a.len);
for(int i = 0;i < len; i++)
{
int sa = a.d[i]=='\0'? 0:a.d[i]-'0',
sb = b.d[i]=='\0'? 0:b.d[i]-'0';
int sum = sa+sb;
if(flag) sum++,flag = 0;
if(sum >= 10) flag = 1, c.d[i] = sum-10 + '0';
else c.d[i] = sum+'0';
}
if(flag) c.d[len++] = 1+'0';
c.len = len;
c.d[len] = '\0';
return c;
}
bool operator<(Bigint a,Bigint b)
{
if(a.len < b.len) return true;
else if(a.len == b.len)
{
int flag = 0;
for(int i = a.len-1; i >= 0; i--)
{
if(a.d[i] == b.d[i]) continue;
if(a.d[i] < b.d[i]) {flag = 1;break;}
else if(a.d[i] > b.d[i]){flag = 0;break;}
}
return flag;
}
return false;
}
bool operator==(Bigint a,Bigint b)
{
if(a.len == b.len && strcmp(a.d,b.d) == 0) return true;
return false;
}
int pre()
{
char a1[10] = "1", a2[10] = "2";
fib[1] = Bigint(a1); fib[2] = Bigint(a2);
for(int i = 3; i < 500; i++)
{
fib[i] = fib[i-1] + fib[i-2];
//cout<<"i fib "<<i<<" "<<fib[i].d<<endl;
}
}
char a[105], b[105];
char c[maxn],d[maxn];
int main()
{
pre();
while(~scanf("%s%s",a,b))
{
if(a[0] == '0' && b[0] == '0') break;
int alen = strlen(a), blen = strlen(b);
for(int i = 0; i < alen; i++)
c[i] = a[alen-i-1];
c[alen] = '\0';
for(int i = 0; i < blen; i++)
d[i] = b[blen-i-1];
d[blen] = '\0';
//cout<<c<<" "<<d<<endl;
Bigint tempa = Bigint(c),tempb = Bigint(d);
int st = 0,sp = 0,flag = 0;
//cout<<tempa.d<<endl;
//cout<<(tempa<fib[6])<<endl;
for(int i = 1; i < 500; i++)
{
if(st && sp) break;
if((fib[i] == tempa||tempa < fib[i]) && !st ) {st = i;}
if((fib[i] == tempb||tempb < fib[i]) && !sp ) {sp = i-1;}
if(fib[i] == tempb) sp++;
}
cout<<sp-st+1<<endl;
}
return 0;
}
题目描述
1.取一个实心的三角形。(多数使用等边三角形)
2.沿三边中点的连线,将它分成四个小三角形。
3.去掉中间的那一个小三角形。
4.对其余三个小三角形重复1。
我们想尝试用斜线、反斜线和下划线画出谢尔宾斯基三角,假设最小的三角是长这样的:
/\
/__\
输入
多组数据输入输出。每行有一个整数n(1<=n<=10),表示执行了一次操作1,n=0时结束输入。
输出
画出执行n次操作1后的图形,调整你的输出到最左端(底边的第一个斜杠在第一列)。输出不能包含任何尾随空格。在每个测试用例后打印空行。
样例输入
3
2
1
0
样例输出
/\
/__\
/\ /\
/__\/__\
/\ /\
/__\ /__\
/\ /\ /\ /\
/__\/__\/__\/__\
/\
/__\
/\ /\
/__\/__\
/\
/__\
代码:
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
const int maxn = 1500<<1;
char s[maxn][maxn];
int po(int x)
{
int ans = 1;
for(int i = 1; i <= x; i++)
ans *= 2;
return ans;
}
void solve(int n,int x,int y,int len)
{
if(n == 0) return;
int stx = x, sty = y-1;
for(int i = 0; i < len; i++)
s[x-i][++sty] = '/';
for(int i = 0; i < len; i++)
s[x-len+1+i][++sty] = 92;
while(sty > y+1)
s[x][--sty] = '_';
solve(n-1,x,y,po(n-1));
solve(n-1,x,y + len , po(n-1));
solve(n-1,x - len/2, y + len/2, po(n-1));
}
int main()
{
int n;
while(~scanf("%d",&n) && n)
{
memset(s,' ',sizeof(s));
int len = po(n);
solve(n,len-1,0,len);
int y = len+1;
for(int i = 0; i < len; i++)
s[i][y++] = '\0';
for(int i = 0; i < len; i++)
cout<<s[i]<<endl;
cout<<endl;
}
return 0;
}