【一场模拟赛?】

JSH师兄来讲课,于是也弄了场比赛给我们做。。。被虐。。。

A.简单的图论题

嗯求一个拓扑图中每个点的可达点数量,n=10000

嗯记忆化搜索,但是有可能搜到重复的点,于是我们不搜索可达点数量,转成搜索可达点集,这个可以用一个bool数组记录。

于是STL有某种东西叫做bitset(长知识

// Problem#: 14938
// Submission#: 3794800
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cctype>
#define rep(i, l, r) for(int i=l; i<=r; i++)
#define down(i, l, r) for(int i=l; i>=r; i--)
#define clr(x, c) memset(x, c, sizeof(x))
#define travel(x) for(edge *p=fir[x]; p; p=p->n)
#define maxn 10009
#define maxm 50009
#define inf 0x7fffffff
#define Q 1000000007 
#define ll long long
using namespace std;
int read()
{
    int x=0, f=1; char ch=getchar();
    while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while (isdigit(ch)) x=x*10+ch-'0', ch=getchar();
    return x*f;
}
struct edge{int y; edge *n;} e[maxm], *fir[maxn], *pt=e;
void AddE(int x, int y){pt->y=y, pt->n=fir[x], fir[x]=pt++;}
int n, m, f[maxn];
ll b[maxn][200];
bool v[maxn];
void dfs(int x)
{
    v[x]=1; b[x][x/50]=(ll)1<<(x%50);
    travel(x) if (!v[p->y]) dfs(p->y);
    travel(x) rep(i, 0, 199) b[x][i]|=b[p->y][i];
}
void Init(){clr(fir, 0); pt=e; clr(f, 0); clr(v, 0);}
int main()
{
    int t=read(); while (t--)
    {
        n=read(), m=read();
        Init();
        rep(i, 1, m){int x=read(), y=read(); AddE(x, y);}
        rep(i, 0, n-1) if (!v[i]) dfs(i);
        rep(i, 0, n-1) rep(j, 0, 199)
        {
            while (b[i][j]) f[i]+=b[i][j]&1, b[i][j]>>=1;
        }
        rep(i, 0, n-1) printf("%d%c", f[i], i==(n-1)?'\n':' ');
    }
    return 0;
}                                 

B.最大价值

懒得说题目。。。

贪心+排序后Dp

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cctype>
#define rep(i, l, r) for(int i=l; i<=r; i++)
#define down(i, l, r) for(int i=l; i>=r; i--)
#define clr(x, c) memset(x, c, sizeof(x))
#define travel(x) for(edge *p=fir[x]; p; p=p->n)
#define maxn 10009
#define inf 0x7fffffff
#define ll long long
using namespace std;
int read()
{
    int x=0, f=1; char ch=getchar();
    while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while (isdigit(ch)) x=x*10+ch-'0', ch=getchar();
    return x*f;
}
struct node{double a,b;} q[maxn];
bool cmp(node a, node b){return a.a/(a.b-1)>b.a/(b.b-1);}
int n, k;
double f[25][maxn];
int main()
{
    int t=read(); while (t--)
    {
        n=read(); k=read();
        rep(i, 1, n) scanf("%lf%lf", &q[i].a, &q[i].b);
        sort(q+1, q+1+n, cmp); clr(f, 0);
        rep(i, 1, k) 
        {
            double m=0;
            rep(j, 1, n) f[i][j]=m*q[j].b+q[j].a, m=max(m, f[i-1][j]);
        }
        double ans=0;
        rep(i, 1, n) ans=max(ans, f[k][i]);
        printf("%.2lf\n", ans);
    }
    return 0;
}                                 

C.选择

水题

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cctype>
#define rep(i, l, r) for(int i=l; i<=r; i++)
#define clr(x, c) memset(x, c, sizeof(x))
#define travel(x) for(edge *p=fir[x]; p; p=p->n)
#define maxn 1000009
#define Q 1000000
#define inf 0x7fffffff
#define ll long long
using namespace std;
int read()
{
    int x=0, f=1; char ch=getchar();
    while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while (isdigit(ch)) x=x*10+ch-'0', ch=getchar();
    return x*f;
}/* 
struct edge{int y; edge *n;} e[maxm], *fir[maxn], *pt=e;
void AddE(int x, int y){pt->y=y, pt->n=fir[x]; fir[x]=pt++;} */
int c[maxn];
bool b[maxn];
int main()
{
    b[1]=1;
    rep(i, 1, (int)sqrt(Q)) if (!b[i])
        for(int a=i+i; a<=Q; a+=i) b[a]=1;
    int a=0; rep(i, 1, Q) if (!b[i]) c[i]=++a;
    for(int w=read(); w>0; w=read()) printf("%d\n", c[w]);
    return 0;
}                                 

D.寻找第K小

a数组和b数组先从小到大排序

二分答案ans,然后每行都二分查找有多少个小于ans的值。两个log

或者不二分查找了,直接从右上角走到左下角。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cctype>
#define rep(i, l, r) for(int i=l; i<=r; i++)
#define clr(x, c) memset(x, c, sizeof(x))
#define travel(x) for(edge *p=fir[x]; p; p=p->n)
#define maxn 20009
#define inf 0x7fffffff
#define ll long long
using namespace std;
int read()
{
    int x=0, f=1; char ch=getchar();
    while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while (isdigit(ch)) x=x*10+ch-'0', ch=getchar();
    return x*f;
}/* 
struct edge{int y; edge *n;} e[maxm], *fir[maxn], *pt=e;
void AddE(int x, int y){pt->y=y, pt->n=fir[x]; fir[x]=pt++;} */
int n, m, k;
ll c[maxn], d[maxn];
bool can(ll x)
{
    int now=0;
    rep(i, 1, n) 
    {
        int l=0, r=m, mid;
        while (l<r)
        {
            mid=((l+r)>>1)+1;
            if (c[i]*d[mid]>=x) r=mid-1; else l=mid;
        }
        now+=l; if (now>k-1) return 1;
    }
    return 0;
}
int main()
{
    int t=read(); while (t--)
    {
        n=read(), m=read(); k=read();
        rep(i, 1, n) c[i]=read(); sort(c+1, c+1+n);
        rep(i, 1, m) d[i]=read(); sort(d+1, d+1+m);
        ll L=1, R=0xDE0B6B3A7640000;
        while (L<R)
        {
            ll mid=((L+R)>>1)+1;
            if (can(mid)) R=mid-1; else L=mid;
        }
        printf("%lld\n", L);
    }
    return 0;
}                                 

E.最强密码

好题!(百度之星的原题Orz

嗯先处理出含有a-z的块的个数,ans既是块数+1

然后记忆化搜索+剪纸(具体看程序把

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cctype>
#define rep(i, l, r) for(int i=l; i<=r; i++)
#define down(i, l, r) for(int i=l; i>=r; i--)
#define clr(x, c) memset(x, c, sizeof(x))
#define travel(x) for(edge *p=fir[x]; p; p=p->n)
#define maxn 100009
#define inf 0x7fffffff
#define Q 1000000007 
#define ll long long
using namespace std;
int read()
{
    int x=0, f=1; char ch=getchar();
    while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while (isdigit(ch)) x=x*10+ch-'0', ch=getchar();
    return x*f;
}
int l, a, tot, st[4009], c[maxn][26];
ll all, p[4009], f[4009][26];
char s[maxn];
bool b[26];
ll dfs(int k, int x, int y)
{
    if (k==0) return 1;
    if (x<=st[k]) return p[k];
    if (k!=a+1 && f[k][y]) return f[k][y];
    int now=0;
    rep(i, 0, 25) if (c[x][i])
        now=(now+dfs(k-1, c[x][i], i))%Q;
    return f[k][y]=now;
}
int main()
{
    p[0]=1; rep(i, 1, 4000) p[i]=p[i-1]*26%Q;
    int t=read(), Case=0; while (t--)
    {
        scanf("%s", s); l=strlen(s); Case++;
        clr(c, 0); down(i, l-1, 0) 
        {
            rep(j, 0, 25) c[i][j]=c[i+1][j];
            c[i][s[i]-'a']=i+1;
        }
        clr(st, 0); tot=26; clr(b, 0); a=0;
        down(i, l-1, 0) 
        {
            if (!b[s[i]-'a']) tot--; b[s[i]-'a']=1;
            if (!tot) a++, clr(b, 0), tot=26, st[a]=i;
        }
        st[a+1]=-1; clr(f, 0);
        printf("Case #%d:\n%d %lld\n", Case, a+1, (p[a+1]-dfs(a+1, 0, 0)+Q)%Q);
    }
    return 0;
}                                 

于是乎依旧被虐得很惨QAQ

posted @ 2015-07-01 21:44  NanoApe  阅读(342)  评论(0编辑  收藏  举报
AmazingCounters.com