2016-11-12试题解题报告

By shenben

本解题报告解析均为100分解题思路。

T1
枚举+乘法原理(+容斥原理)
滚动枚举最短的S串在T串的头和尾,然后用乘法原理当前的x。
ans=∑x(注意S串是类似“aabb”这种情况)
T2
dp
第一问:
根据题目中的伪代码,一个点一定会与位于这个点之后并且不大于这个点的点连一条边,样例中3会与1和2连一条边,而1就不会与2连边,这样就构成了一个下降的序列。那么反过来,不连边的点就构成了上升序列,这就是一个点独立集,最大的点独立集就是最长上升子序列。所以第一问的答案就是最长上升子序列的长度。 
第二问:
问哪些点在最长上升子序列中必不可少。
因为最长上升子序列可能有多个,那么所有上升子序列中公共的点就是一定在最大点独立集中的点。

T3
。。
暂时不知道

T1代码
AI版

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
#ifdef unix//ifdef千万别再写错了区别 ifndef(×)
#define LL "%lld"
#else
#define LL "%I64d"
#endif
using namespace std;
const int N=3e5+10,M=210;
const int inf=0x3f3f3f;
char t[N],s[M];
int n,m,cnt,near[N][30];
int head[N],tail[N];
void special_judge(){
    int p=-1;ll ans=0;
    for(int i=0;i<m;i++){
        if(t[i]!=s[0]) continue;
        ans+=(ll)(i-p)*(ll)(m-i);
        p=i;
    }
    printf(LL,ans);
}
#define name "encrypt"
int main(){
    freopen(name".in","r",stdin);
    freopen(name".out","w",stdout);
    gets(t);gets(s);
    m=strlen(t);n=strlen(s);
    if(n==1){special_judge();return 0;}
    //near[i][j]表示距离t[i]右边最近的a~z的下标
    for(int i=1;i<=26;i++) near[m][i]=inf;
    for(int i=m-1;i>=0;i--){
        for(int j=1;j<=26;j++){
            if(t[i]==j+‘a‘-1) near[i][j]=0;
            else if(near[i+1][j]==inf) near[i][j]=inf;
            else near[i][j]=near[i+1][j]+1;
        }
    }
    for(int i=0;i<=m;i++){
        for(int j=1;j<=26;j++){
            if(!near[i][j]){//aabb这种情况的更新
                near[i][j]=near[i+1][j]+1;
            }
        }
    }
    for(int i=0;i<m;i++){
        if(t[i]!=s[0]) continue;
        int j=i,zj=1;
        for(;j<inf&&zj<n;zj++)j+=near[j][s[zj]-‘a‘+1];
        if(zj==n&&j<inf) head[++cnt]=i,tail[cnt]=j;
    }
    ll ans=0;head[0]=-1;//乘法原理
    for(int i=1;i<=cnt;i++) ans+=(ll)(head[i]-head[i-1])*(ll)(m-tail[i]);
    printf(LL,ans);
    fclose(stdin);
    fclose(stdout);
    return 0;
}

简短精炼的std

#include<cstdio>
#include<cstring>
#include<iostream>
#define ll long long
#ifdef unix
#define LL "%lld"
#else
#define LL "%I64d"
#endif
using namespace std;
const int N=3e5+10;
const int M=210;
char t[N],s[M];
int n,m,f[M];
ll ans;
#define name "encrypt"
int main(){
    freopen(name".in","r",stdin);
    freopen(name".out","w",stdout);
    gets(t+1);
    gets(s+1);
    n=strlen(t+1);
    m=strlen(s+1);
    for(int i=1;i<=m;i++) f[i]=n+1;
    for(int i=n;i;i--){
        f[m+1]=i;
        for(int j=1;j<=m;j++){
            if(t[i]==s[j]){
                f[j]=min(f[j],f[j+1]);
            }
        }
        ans+=n-f[1]+1;
    }
    printf(LL,ans);
    fclose(stdin);
    fclose(stdout);
    return 0;
}

T2代码

#include<cstdio>
#include<algorithm>
#define R register
using namespace std;
inline int read(){
    R int x=0;bool f=1;
    R char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=0;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘){x=(x<<3)+(x<<1)+ch-‘0‘;ch=getchar();}
    return f?x:-x;
}
const int N=1e5+10;
int n,len,a[N],b[N],f[N],maxx[N],sum[N];
bool vis[N];
#define name "bubble"
int main(){
    freopen(name".in","r",stdin);
    freopen(name".out","w",stdout);
    n=read();
    for(int i=1;i<=n;i++) a[i]=read();
    b[len=1]=a[1];f[1]=1;
    for(int i=2,pos;i<=n;i++){
        if(a[i]>b[len]){
            b[++len]=a[i];
            f[i]=len;
        }
        else{
            pos=lower_bound(b+1,b+len,a[i])-b;
            b[pos]=a[i];
            f[i]=pos;
        }
    }
    printf("%d\n",len);
    for(int i=n;i;i--){
        if(f[i]==len||maxx[f[i]+1]>a[i]){
            vis[i]=1;sum[f[i]]++;
            maxx[f[i]]=max(maxx[f[i]],a[i]);
        }
    }
    for(int i=1;i<=n;i++) if(vis[i]&&sum[f[i]]==1) printf("%d ",i);
    fclose(stdin);
    fclose(stdout);
    return 0;
}

T3代码]

暂无AC代码

/*20分存档
#include<cstdio>
#include<cstring>
#include<stack>
#include<vector>
#include<iostream>
#include<algorithm>
#define R register
#define debug(x,y) cout<<x<<"---"<<y<<endl
#define ll long long
#ifdef unix
#define LL "%lld"
#else
#define LL "%I64d"
#endif
using namespace std;
inline ll read(){
    R ll x=0;bool f=1;
    R char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=0;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘){x=(x<<3)+(x<<1)+ch-‘0‘;ch=getchar();}
    return f?x:-x;
}
const ll N=2001;
const ll QLEN=N*4-5;
const ll inf=2e9;
ll n,m,pd,sd,dfn[N],low[N],sum[N];
bool mark[N],vis[N];
ll b[N][N];
stack<ll>s;
struct node{
    ll id,v;
    node(){id=0;v=0;}
    bool operator <(const node &a) const{
        return v>a.v;
    }
}ind[N],outd[N];
struct ss{
    ll id,val;
    ss(){id=0;val=0;}
    ss(ll _id,ll _val){
        id=_id;
        val=_val;
    }
    bool operator <(const ss &a) const{
        if(val==a.val) return id<a.id;
        return val>a.val;
    }
}dis[N];
void tarjan(ll v){
    dfn[v]=low[v]=++pd;
    mark[v]=1;
    s.push(v);
    for(ll w=1;w<=n;w++){
        if(b[v][w]){
            if(!dfn[w]){
                tarjan(w);
                low[v]=min(low[v],low[w]);
            }
            else if(mark[w]){
                low[v]=min(low[v],dfn[w]);
            }
        }
    }
    ll u;
    if(low[v]==dfn[v]){
        sd++;
        do{
            u=s.top();s.pop();
            sum[sd]++;
            mark[u]=0;
        }while(u!=v);
    }
}
ll q[N<<2]={0};
ll ans[N];
ll sans[N];
inline void spfa(ll S){
    ll h=0,t=1;
    for(ll i=1;i<=n;i++) dis[i].id=i;
    for(ll i=1;i<=n;i++) dis[i].val=-inf;
    dis[S].val=0;
    vis[S]=1;
    q[t]=S;
    while(h<t){
        if(++h>QLEN) h=1;
        ll x=q[h];
        vis[x]=0;
        for(ll i=1;i<=n;i++){
            if(b[x][i]){
                ll v=i;
                if(dis[v].val<dis[x].val+1){
                    dis[v].val=dis[x].val+1;
                    if(!vis[v]){
                        vis[v]=1;
                        if(++t>QLEN) t=1;
                        q[t]=v;
                    }
                }
            }
        }
    }
    //printf("%d",dis[T]);
}
void Cl(){
    sd=0;pd=0;
    memset(dfn,0,sizeof dfn);
    memset(low,0,sizeof low);
    memset(sum,0,sizeof sum);
    memset(vis,0,sizeof vis);
    memset(mark,0,sizeof mark);
    while(!s.empty()) s.pop();
}
#define name "rebuild"
int main(){
    freopen(name".in","r",stdin);
    freopen(name".out","w",stdout);
    Cl();
    n=read();m=read();
    for(ll i=1,x,y;i<=m;i++){
        x=read();y=read();
        outd[x].id=x;outd[x].v+=1;
        b[x][y]=i;
    }
    for(ll i=1;i<=n;i++) if(!dfn[i]) tarjan(i);
    sort(sum+1,sum+sd+1,greater<ll>());
    if(sum[1]==n){
        printf(LL"\n"LL"\n",n,m);
        for(ll i=1;i<=m;i++) printf("%d ",i);
        return 0;
    }
    sort(outd+1,outd+n+1);
    spfa(outd[1].id);
    sort(dis+1,dis+n+1);
    printf(LL"\n",dis[1].val+1);
    ll tv=dis[1].val;ans[++ans[0]]=dis[1].id;
    for(ll i=2;i<=n;i++) if(dis[i].val==tv) ans[++ans[0]]=dis[i].id;
    for(ll i=1,z=outd[1].id,pt,x,y;i<=ans[0];i++){
        pt=ans[i];
        if(b[z][pt]) sans[++sans[0]]=b[z][pt];
        if(b[pt][z]) sans[++sans[0]]=b[pt][z];
    }
    sort(sans+1,sans+sans[0]+1);
    ll cnt=unique(sans+1,sans+sans[0]+1)-(sans+1);
    printf(LL"\n",cnt);
    for(ll i=1;i<=cnt;i++){
        printf(LL" ",sans[i]);
    }
    fclose(stdin);
    fclose(stdout);
    return 0;
}*/
时间: 2024-08-11 00:26:40

2016-11-12试题解题报告的相关文章

2016.8.29 LGTB解题报告

考试总结: 1.这道题还是花了不少的时间的,特别是对拍啊之类的,总是放不下,然后有一些实现的问题导致改错也改了很久: 解决方案:下一次在决定写程序的时候,一定要先在草稿纸上把实现算法的流程基本上写一次,精确到循环语句,判断语句的框架,把所有的情况都完整地考虑一次,确定没有问题了再写: 这道题犯了和上一套第二题同样的问题:证明的时间过长: 解决方案:在解题时把流程规范化,在证明了算法正确性以后就放下了,不要总是把它提出来! 2.这道题的数据范围特别小,所以可以很容易地想到状压DP,然后考虑到互质的

济南-1030试题解题报告

By shenben 本解题报告解析均为100分解题思路. 上午 T1 题意:从1− n中找一些数乘起来使得答案是一个完全平方数,求这个完全平方数 最大可能是多少. 解析: 1.  质因数分解 2.  1->n用质因数指数的相加的形式将1*n累乘起来 3.  扫一遍指数为奇数的质因数都-1,偶数的不变 4.  快速幂乘一遍,同时取模 T2 题意:有n个数,随机选择一段区间,如果这段区间的所有数的平均值在[L,R]中则 你比较厉害.求你比较厉害的概率 解析:(暴力枚举 40分) 100分需要推式子

济南-1029试题解题报告

By shenben 本解题报告解析均为100分解题思路. 上午 T1 题意:给你两个日期,问这两个日期差了多少毫秒 解析:标程用ctime库函数写的,编译器版本高了才会过(NOIP编译器版本不会太高): 只能老老实实打模拟. 小技巧:最后多输出“000”,计算秒就好了.(特判两个时间相同,只输出“0”) T2 题意:有m个站口,有n个人按顺序排队,求n+1个人最少等多长时间 解析:(标程显然 同下) ①n<m 输出0(显然) ②n>=m 建一个小根堆(可以用优先队列),把前m个人的时间扔到堆

2016/11/12

我终于打拍了,分数果然好看了很多. 但是并没有A掉第三题 做法:求最长上升子序列 有两个原因:1.想多了,,以为要从上升和下降中取最优值,,结果还丢分了 2.虽然看过nlogn的最长上升子序列求法 ,但是并没有仔细看,考试的时候自己瞎扯了一个90分算法(实在想不起log是哪里来的了) 看了nlogn的做法后,发现差别在于我没有使用二分查找,改进之后会快很多 首先附上90分的瞎扯代码 1 #include<iostream> 2 #include<cstring> 3 #includ

2016.11.12 做题感想

细数一下这两天做过的值得总结的一些题Orz...... HDU 2571 简单dp,但是一开始WA了一发.原因很简单:没有考虑仔细. 如果指向该点的所有点权值都为负数,那就错了(我一开始默认初始值为0) 这是非常基础的典型DAG模型,好久不做,手明显生了-- 1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 #define REP(i,n) for(int i(0); i < (n); ++i) 6 #define rep(i

2016-11-15试题解题报告

By shenben T1代码: #include<cstdio> #include<algorithm> using namespace std; inline int read(){ register int x=0;bool f=1; register char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=0;ch=getchar();} while(ch>='0'&&ch<='9'

2016-11-17试题解题报告

By shenben 水灾(sliker.cpp/c/pas) 1000MS  64MB 大雨应经下了几天雨,却还是没有停的样子.土豪CCY刚从外地赚完1e元回来,知道不久除了自己别墅,其他的地方都将会被洪水淹没. CCY所在的城市可以用一个N*M(N,M<=50)的地图表示,地图上有五种符号:“. * X D S”.其中“X”表示石头,水和人都不能从上面经过.“.”表示平原,CCY和洪水都可以经过.“*”表示洪水开始地方(可能有多个地方开始发生洪水).“D”表示CCY的别墅.“S”表示CCY现

2020.3.28 UCF Local Programming Contest 2016补题与解题报告

A.Majestic 10 大致题意就是指看有几个大于等于10,直接按照题意输出就行,签到题 代码: #include<stdio.h> int main(){ int n,a,b,c; scanf("%d",&n); while(n--){ scanf("%d %d %d",&a,&b,&c); int sum=0; printf("%d %d %d\n",a,b,c); if(a>=10) s

20161109模拟赛解题报告

2016-11-09试题解题报告 By shenben 本解题报告解析均为100分解题思路. T1 模拟即可. 我怕极限数据5000(n,m)*100000(k). 如果用二维数组.空间勉强撑住,时间上够呛. 因此用2个一位数组分别代表行和列. 这样每次修改是O(1)的. 查询是O(nm)(只查询一次) 总时间复杂度:O(nmk) T2 搜索 一开始想偏了. 倒着由“a”往前推.结果小样例过了,大样例差太多. 于是另辟蹊径. 观察到数据范围很小. 直接枚举答案序列不就好了. 对于每个序列再判断一