NEUQ网络赛补题

今天写了部分补题。

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;
}


C

题目描述

这是一个斐波那契数列:
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;
}


D

题目描述

谢尔宾斯基三角形是一种分形,它的构造过程是这样的:
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;
}
 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值