图灵杯

//E.RMQ的变式
/*
统计每个数出现的次数,形成一个新的Count数组,对数组进行sparse table的算法。
次数的最值分为三种情况 1.同区间 2.相邻区间 3. 中间含有完整区间。
*/
typedef int Arr[maxn];
Arr a, Count, Left, Right, Re;
int dp[maxn][25];
int n, q;

void Judge(int re) {
    for(int i = 0; i <= re; i++) {
        printf("%d: left = %d, right = %d, count = %d\n", i, Left[i], Right[i], Count[i]);
    }
}

void Get_Max(int re) {
    for(int i = 0; i <= re; i++) dp[i][0] = Count[i];
    for(int j = 1; j < 25; j++)
        for(int i = 0; i <= re; i++)
            if(i+(1<<j)-1 <= re) {
                dp[i][j] = max(dp[i][j-1], dp[i+(1<<(j-1))][j-1]);
                //printf("%d\n", dp[i][j]);
            }
}

int RMQ(int l, int r) {
    int k = log(r-l+1)/log(2);
    return max(dp[l][k], dp[r-(1<<k)+1][k]);
}

int main() {
    while(scanf("%d", &n) && n) {
        CLEAR(dp, 0);
        CLEAR(Count, 0);
        if(n == 0) break;
        scanf("%d", &q);
        int re = 0;
        Left[re] = 0;
        for(int i = 0; i < n; i++) {
            scanf("%d", &a[i]);
            if(i && a[i] != a[i-1]) {
                re++;
                Left[re] = i;
                Right[re-1] = i-1;
            }
            Count[re]++;
            Re[i] = re; //printf("re = %d\n", re);
        }
        Right[re] = n-1; //Judge(re);
        Get_Max(re);
        int l, r, rel, rer, ans;
        while(q--) {
            scanf("%d%d", &l, &r);
            l--; r--;
            rel = Re[l]; rer = Re[r];
            //printf("rel = %d, rer = %d\n", rel, rer);
            if(rel == rer) ans = r - l + 1;
            else if(rel+1 == rer) ans = max(r-Left[rer]+1, Right[rel]-l+1);
            else {
                ans = max(r-Left[rer]+1, Right[rel]-l+1);
                ans = max(ans, RMQ(rel+1, rer-1));
                //printf("rmq = %d\n", RMQ(rel+1, rer-1));
                //printf("r = %d, l = %d\n", r-Left[rer]+1, Right[rel]-l+1);
            }
            printf("%d\n", ans);
        }
    }
    return 0;
}

//D.运用递归输出图形
char a[2050][2050];
 
void Paint(int x, int y) {
    a[x+1][y-1] = a[x][y] = '/';
    a[x+1][y+2] = a[x][y+1] = '\\';
    a[x+1][y] = a[x+1][y+1] = '_';
}
 
void Draw(int x, int y, int n) {
    if(n == 1) Paint(x, y);
    else if(n >= 2) {
        int t = 1<<(n-1);
        Draw(x, y, n-1);
        Draw(x+t, y-t, n-1);
        Draw(x+t, y+t, n-1);
    }
}
 
void Print(int n) {
    int t = (1 << n);
    for(int i = 1; i <= t; i++) {
        for(int j = 1; j <= t+i; j++)
            cout << a[i][j];
        puts("");
    }
}
 
int main() {
    int n;
    while(cin >> n) {
        CLEAR(a, ' ');
        int y = 1<<n;
        Draw(1, y, n);
        Print(n);
        puts("");
    }
    return 0;
}
//问题 J: 简单的变位词
//(STL,set,map)
typedef multiset<string> Set;
vector<Set> SetCache;
map<string, int> ID;

string stand(string s) {
    string ss(s);
    sort(ss.begin(), ss.end());
    return ss;
}

void solve(string s) {//映射到vector的下表
    string ss = stand(s);
    if(!ID.count(ss)) {
        Set se;
        se.insert(s);
        SetCache.push_back(se);
        ID[ss] = SetCache.size()-1;
    }
    else SetCache[ID[ss]].insert(s);
}

bool cmp(const Set a, const Set b) {
    if(a.size() > b.size()) return 1;
    else if(a.size() == b.size()) {
        if(*(a.begin()) < *(b.begin())) return 1;
    }
    return 0;
}

void print() {//用set倒一遍去重
    for(unsigned int i = 0; i < SetCache.size(); i++) {
        if(i == 5) break;
        cout << "Group of size "<< SetCache[i].size() << ": ";
        set<string> un(SetCache[i].begin(), SetCache[i].end());
        for(auto j = un.begin(); j != un.end(); j++) {
            cout << *j << ' ';
        }
        puts(".");
    }
}

int main() {
    string s;
    //IN(); OUT();
    while(cin >> s) solve(s);
    sort(SetCache.begin(), SetCache.end(), cmp);
    print();
    return 0;
}
//问题 C: 来简单地数个数
//大数应用
struct BigInterger {
    static const int BASE = 1e8;
    static const int WIDTH = 8;
    vector<int> s;
    BigInterger(LL num = 0) { *this = num; }//使用重载等于号

    BigInterger operator = (LL num) {
        s.clear();//原数清零
        do {
            int x = num % BASE;
            s.push_back(x);
            num /= BASE;
        }while(num);//采用do-while而非while保证为0时成功赋值
        return *this;
    }

    BigInterger operator = (const string &str) {
        s.clear();
        int l = str.size();
        int cnt = (l-1)/WIDTH+1;//ceil除法
        for(int i = 0; i < cnt; i++) {
            int high = l - i*WIDTH;
            int low = max(0, high-WIDTH);
            int x = 0;
            sscanf(str.substr(low, high-low).c_str(), "%d", &x);
            s.push_back(x);
        }
        return *this;
    }

    BigInterger operator + (const BigInterger& b) const {
        BigInterger c;
        c.s.clear();
        int re = 0;
        for(unsigned i = 0; ; i++) {
            if(re == 0 && i >= s.size() && i >= b.s.size()) break;
            int x = re;
            if(i < s.size()) x += s[i];
            if(i < b.s.size()) x += b.s[i];
            c.s.push_back(x%BASE);
            re = x / BASE;
        }
        return c;
    }

    bool operator < (const BigInterger &b) const {
        if(s.size() != b.s.size()) return s.size() < b.s.size();
        for(int i = s.size()-1; i >= 0; i--)
            if(s[i] != b.s[i]) return s[i] < b.s[i];
        return false;
    }
    bool operator <= (const BigInterger &b) const {
        return !(b < *this);
    }
    bool operator > (const BigInterger &b) const {
        return !(*this <= b);
    }
    bool operator == (const BigInterger &b) const {
        return !(*this > b) && !(*this < b);
    }
};

ostream &operator << (ostream &out, const BigInterger &x) {
    out << x.s.back();
    for(int i = x.s.size()-2; i >= 0; i--) {
        char buf[10];
        sprintf(buf, "%08d", x.s[i]);//保留前导零
        out << buf;
    }
    return out;
}

istream &operator >> (istream &in, BigInterger &x) {
    string s;
    if(!(in >> s)) return in;
    x = s;
    return in;
}

int main() {
    BigInterger x, y, z = 0;
    while(cin >> x >> y) {
        if(x == z && y == z) break;
        BigInterger a = 1, b = 2, c = 0;
        int cnt = 0;
        for(int i = 0; ; i++) {
            if(x <= a && a <= y) cnt++;
            if(a > y) break;
            c = a+b;
            a = b;
            b = c;
        }
        cout << cnt << endl;
    }
    return 0;
}




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值