zoukankan      html  css  js  c++  java
  • 补题0%……计划进行中

    MDZZ题目长死了,题意大概是给你一个句子,把它全排序,然后下面给你要你匹配的句子,问你,排序后逆序数最少,并且能匹配成功的那个编号,如果逆序数一样的话,就输出最小的那个编号,然后后面输出的东西就是照着题意给的那个式子。
    #include <iostream>
    #include <stdio.h>
    #include <cstdlib>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    #include <stack>
    #include <map>
    #include <set>
    #include <string>
    #include <vector>
    #include <queue>
    #include <ctime>
    #define cl(A) memset(A, 0, sizeof(A))
    #define lowbit(x) (x & -x)
    using namespace std;
    typedef long long LL;
    const int mod=1e9+7;
    const int maxn=2e5+10;
    const int inf=0x3f3f3f3f;
    struct node {
        char s[25][15];
        int k;
    } st[15];
    int num[10];
    char l[10][15];
    int main() {
    #ifdef local
        freopen("in", "r", stdin);
    #endif
        int n,m;
        cin>>n;
        for(int i = 0; i < n ; i++) {
            scanf("%s",l[i]);
            num[i]=i;
        }
        cin>>m;
        for(int i=0; i<m; i++) {
            scanf("%d",&st[i].k);
            for(int j=0; j<st[i].k; j++)
                scanf("%s",st[i].s[j]);
        }
        int p=20,ans=inf;
        do {
            int nixu=0;
            for(int i=0; i<n; i++) {
                for(int j=0; j<i; j++) {
                    if(num[j]>num[i])nixu++;
                }
            }
            if(nixu>ans)continue;
            for(int i=0; i<m; i++) {
                int pi=0;
                for(int j=0; j<st[i].k&&pi<n; j++) {
                    if(strcmp(l[num[pi]],st[i].s[j])==0)pi++;
                }
                if(pi==n&&(nixu<ans||(ans==nixu&&p>i))) {
                    p=i;
                    ans=nixu;
                }
            }
        } while(next_permutation(num,num+n));
        if(ans==inf) {
            puts("Brand new problem!");
        } else {
            printf("%d
    ",p+1);
            printf("[:");
            for(int i=0; i<n*(n-1)/2+1-ans; i++)putchar('|');
            puts(":]");
        }
    }
    View Code

    Gym 100676F

    发现以前做不出真是有点脑残。。这么水的并查集。题意问给你一串长度为n的字符串,里面有可能包含'?'还有小写字母,还有m个操作,每个有a,b表示这两个位置的字符相同,然后问你有几种方案使得这个字符串变成回文串。边判边并起来就行了。最后答案就是26^cnt.

    #include <iostream>
    #include <stdio.h>
    #include <cstdlib>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    #include <stack>
    #include <map>
    #include <set>
    #include <string>
    #include <vector>
    #include <queue>
    #include <ctime>
    #define cl(A) memset(A, 0, sizeof(A))
    #define lowbit(x) (x & -x)
    using namespace std;
    typedef long long LL;
    const int mod=1e9+7;
    const int maxn=2e5+10;
    const int inf=0x3f3f3f3f;
    int fa[500005];
    char s[500005];
    void init(int n){
        for(int i=0;i<=n;i++)
            fa[i]=i;
    }
    int finds(int x){
        if(fa[x]==x)return x;
        return fa[x]=finds(fa[x]);
    }
    void uf(int a,int b){
        if(a==b)return;
        if(s[a]!='?')
            fa[b]=a;
        else
            fa[a]=b;
    }
    int main() {
    #ifdef local
        freopen("in", "r", stdin);
    #endif
        int T;
        scanf("%d",&T);
        while(T--){
            bool flag=1;
            int n,m;
            scanf("%d%d",&n,&m);
            init(n);
            scanf("%s",s);
            for(int i=0;i<n;i++){
                if(s[i]!='?'&&s[n-i-1]!='?'&&s[i]!=s[n-i-1])flag=0;
                else if(s[i]=='?')s[i]=s[n-i-1];
                else s[n-i-1]=s[i];
            }
            for(int i=0;i<m;i++){
                int a,b;
                scanf("%d%d",&a,&b);
                --a,--b;
                a=finds(a);
                b=finds(b);
                if(s[a]!='?'&&s[b]!='?'&&s[a]!=s[b])flag=0;
                if(flag)uf(a,b);
            }
            for(int i=0,j=n-1;i<n/2;i++,j--){
                int a,b;
                a=finds(i);
                b=finds(j);
                if(s[a]!='?'&&s[b]!='?'&&s[a]!=s[b])flag=0;
                if(flag)uf(a,b);
            }
            if(!flag)cout<<0<<endl;
            else {
    
                int cnt=0;
                for(int i=0;i<n;i++){
                    int h=finds(i);
                    if(s[h]=='?'&&fa[i]==i){
                            cnt++;
                    }
                }
                LL ans=1;
                for(int i=0;i<cnt;i++)ans=(26*ans)%mod;
                cout<<ans<<endl;
            }
        }
    }
    View Code

     Gym 100676G

    论如何能出一道难题,直接把输入输出方式往死里搞复杂就对了。。状压dp,输入简直蛋疼

    #include <iostream>
    #include <stdio.h>
    #include <cstdlib>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    #include <stack>
    #include <map>
    #include <set>
    #include <string>
    #include <vector>
    #include <queue>
    #include <ctime>
    #define cl(A) memset(A, 0, sizeof(A))
    #define lowbit(x) (x & -x)
    using namespace std;
    typedef long long LL;
    const int mod=1e9+7;
    const int maxn=2e5+10;
    map<string,int>mp;
    int dp[(1<<18)+5];
    int w[20];
    int to[20];
    const int inf=0x3f3f3f3f;
    int n,m;
    char s[205];
    string u,v;
    void init() {
        mp.clear();
        fill(dp, dp + (1 << 18), -inf);
        cl(to);
        cl(w);
        cin>>n>>m;
        getchar();
        for(int i=0;i<n;i++){
            gets(s);
            int len=strlen(s)-1;
            while(s[len]!=' ')len--;
            w[i]=atoi(s+len);
            while(s[len]==' ')len--;
            s[len+1]='';
            mp[string(s)]=i;
        }
        for(int i=0;i<m;i++){
            gets(s);
            int len=strlen(s)-1;
            while(s[len-1]!=' '||s[len-2]!='>')len--;
            int v=len;
            while(s[len+1]!='-'||s[len]!=' ')len--;
            s[len]='';
            to[mp[string(s+v)]]|=(1<<mp[string(s)]);
        }
    }
    void solve() {
        dp[0]=0;
        for(int i=0; i<(1<<n); i++) {
            int cnt=0;
            for(int j=0; j<n; j++) {
                cnt+=((i>>j)&1);
            }
            for(int k=0; k<n; k++) {
                int sta=i|(1<<k);
                if(((i>>k&1)!=0)||((i&to[k])!=to[k]))continue;
                dp[sta]=max(dp[sta],dp[i]+(cnt+1)*w[k]);
            }
        }
        cout<<dp[(1<<n)-1]<<endl;
    }
    int main() {
    #ifdef local
        freopen("in", "r", stdin);
    #endif
        int T;
        scanf("%d",&T);
        while(T--) {
            init();
            solve();
        }
    }
    View Code

     FZU - 2239

    题意就是给你n条直线的k和b,m个询问,每个询问都是一个x问f(x)最大是多少,画图发现,其实就是要维护上面那个凹状的东西,用个栈维护一下,然后把x排序来求

    #include <iostream>
    #include <stdio.h>
    #include <cstdlib>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    #include <stack>
    #include <map>
    #include <set>
    #include <string>
    #include <vector>
    #include <queue>
    #include <ctime>
    #define cl(A) memset(A, 0, sizeof(A))
    #define lowbit(x) (x & -x)
    using namespace std;
    typedef long long LL;
    const int mod=1e9+7;
    const int maxn=1e5+10;
    const double eps=1e-7;
    struct Line {
        int k,b;
        bool operator <(const Line &a)const {
            if(k==a.k)return b>a.b;
            return k<a.k;
        }
    } line[maxn];
    Line sta[maxn];
    double get_in(Line a,Line b) {
        return (double)(b.b-a.b)/(double)(a.k-b.k);
    }
    int n,m;
    LL ans[maxn];
    struct ask {
        int id,x;
        bool operator <(const ask &a)const {
            return x>a.x;
        }
    } ask[maxn];
    void init() {
        for(int i=0; i<n; i++)
            scanf("%d%d",&line[i].k,&line[i].b);
        for(int i=0; i<m; i++) {
            scanf("%d",&ask[i].x);
            ask[i].id=i;
        }
        sort(line,line+n);
        sort(ask,ask+m);
    }
    void solve() {
        int top=0;
        sta[++top]=line[0];
        for(int i=1; i<n; i++) {
            if(line[i].k==line[i-1].k)continue;
            while(top>1&&get_in(line[i],sta[top])<=get_in(sta[top],sta[top-1]))top--;
            sta[++top]=line[i];
        }
        for(int i=0; i<m; i++) {
            while(top>1&&get_in(sta[top],sta[top-1])>=(double)ask[i].x)top--;
            ans[ask[i].id]=1LL*ask[i].x*sta[top].k+sta[top].b;
        }
        for(int i=0; i<m; i++)
            cout<<ans[i]<<endl;
    }
    int main() {
    #ifdef local
        freopen("in", "r", stdin);
    #endif
        while(scanf("%d%d",&n,&m)>0) {
            init();
            solve();
        }
    }
    View Code

     HDU 5745

    bitset压位dp

    #include <iostream>
    #include <stdio.h>
    #include <cstdlib>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    #include <stack>
    #include <map>
    #include <set>
    #include <string>
    #include <vector>
    #include <queue>
    #include <bitset>
    #include <ctime>
    #define cl(A) memset(A, 0, sizeof(A))
    #define lowbit(x) (x & -x)
    using namespace std;
    typedef long long LL;
    const int mod=1e9+7;
    const int maxn=1e5+10;
    const double eps=1e-7;
    const int N=1e5+5;
    const int M=5e3+5;
    //bool dp[N][M][3]用bitset代替第一维度,滚动第二维
    //dp[i][j][0/1/2]分别表示主串在i,模式串在j时,0表示j与j-1交换时是否匹配,1表示不交换,2表示与后面交换
    //dp[i][j][0]=dp[i-1][j-1][2]&(a[i]==b[j-1]);
    //dp[i][j][1]=dp[i-1][j-1][0]|dp[i-1][j-1][1]&(a[i]==b[j]);
    //dp[i][j][2]=dp[i-1][j-1][0]|dp[i-1][j-1][1]&(a[i]==b[j+1]);
    bitset<N>dp[2][3];
    bitset<N>mp[30];
    //表示26位字母对a字符串的匹配状态
    char a[N];
    char b[M];
    int n,m;
    void init() {
        scanf("%d%d",&n,&m);
        scanf("%s%s",a,b);
        for(int i=0;i<26;i++)mp[i].reset();
        for(int i=0;i<2;i++)
            for(int j=0;j<3;j++)dp[i][j].reset();
    }
    void solve() {
        for(int i=0;i<n;i++)mp[a[i]-'a'][i]=1;
        int cur=1;
        dp[cur][1]=mp[b[0]-'a'];
        if(m>1)dp[cur][2]=mp[b[1]-'a'];
        for(int i=1;i<m;i++){
            cur^=1;
            dp[cur][0]=mp[b[i-1]-'a']&(dp[cur^1][2]<<1);
            dp[cur][1]=mp[b[i]-'a']&((dp[cur^1][0]|dp[cur^1][1])<<1);
            if(i+1<m)dp[cur][2]=mp[b[i+1]-'a']&((dp[cur^1][0]|dp[cur^1][1])<<1);
        }
        for(int i=0;i<n;i++){
            if(dp[cur][0][i+m-1]|dp[cur][1][i+m-1])putchar('1');
            else putchar('0');
        }
        putchar('
    ');
    }
    int main() {
    #ifdef local
        freopen("in", "r", stdin);
    #endif
        int T;
        scanf("%d",&T);
        while(T--) {
            init();
            solve();
        }
    }
    View Code

     HDU 5738

    定义在同一直线上至少两个点(可以重合)就可以组成一个完美集合,给n个点,问你有多少这样的集合

    #include <iostream>
    #include <stdio.h>
    #include <cstdlib>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    #include <stack>
    #include <map>
    #include <set>
    #include <string>
    #include <vector>
    #include <queue>
    #include <bitset>
    #include <ctime>
    #define cl(A) memset(A, 0, sizeof(A))
    #define lowbit(x) (x & -x)
    using namespace std;
    typedef long long LL;
    const int mod=1e9+7;
    const int maxn=1e5+10;
    const double eps=1e-7;
    const int N=1e5+5;
    const int M=1e3+5;
    LL bp[M];
    LL ans;
    int n;
    void add(LL &a,LL b) {
        a+=b;
        while(a>=mod)a-=mod;
    }
    struct Point {
        LL x,y;
        bool operator <(const Point &a)const {
            if(x!=a.x)return x<a.x;
            return y<a.y;
        }
    } p[M];
    struct ang {
        double a;
        int x,y;
        bool operator <(const ang &c)const {
            return a<c.a;
        }
    } ang[M];
    void init() {
        ans=0;
        scanf("%d",&n);
        for(int i=0; i<n; i++)
            cin>>p[i].x>>p[i].y;
    }
    void solve() {
        sort(p,p+n);
        int j,k,l;
        for(int i=0; i<n; i++) {
            for(j=i+1; j<n; j++) {
                if(p[i].x==p[j].x&&p[i].y==p[j].y);
                else break;
            }
            j--;
            int ps=j-i+1,cnt=0;
            add(ans,bp[ps]-1-ps);
            for(k=j+1; k<n; k++) {
                ang[cnt].a=atan2((double)(p[k].y-p[i].y),(double)(p[k].x-p[i].x));
                ang[cnt].x=p[k].x;
                ang[cnt++].y=p[k].y;
            }
            sort(ang,ang+cnt);
            for(k=0; k<cnt; k++) {
                for(l=k+1; l<cnt; l++) {
                    if((ang[l].y-p[i].y)*(ang[k].x-p[i].x)!=(ang[k].y-p[i].y)*(ang[l].x-p[i].x))break;
                }
                l--;
                int pn=l-k+1;
                add(ans,((bp[ps]-1)*(bp[pn]-1))%mod);
                k=l;
            }
            i=j;
        }
        cout<<ans<<endl;
    }
    int main() {
    #ifdef local
        freopen("in", "r", stdin);
    #endif
        bp[0]=1;
        for(int i=1; i<M; i++)bp[i]=(bp[i-1]*2)%mod;
        int T;
        scanf("%d",&T);
        while(T--) {
            init();
            solve();
        }
    }
    View Code
  • 相关阅读:
    element ui 日期选择器的各种快捷选项
    vue实现带搜索的模拟下拉框组件
    前端面试100问(31-40)
    前端面试100问(22-30)
    古德-图灵估计(Good-Turing Estimate)
    拉普拉斯平滑(Laplace Smoothing)
    分类 与 聚类
    推荐系统
    文本聚类(Text clustering)
    文本分类(Text Categorization)
  • 原文地址:https://www.cnblogs.com/scau-zk/p/5785530.html
Copyright © 2011-2022 走看看