2015的题比2014丧多了。

T1——神奇的幻方——然而T1还是挺简单的——简单模拟。

#include<iostream>
#include<cstdio>
using namespace std;
int n,a[50][50],x,y;
int main()
{
    scanf("%d",&n);
    x=1;y=(n+1)>>1;a[x][y]=1;
    for(int i=2;i<=n*n;i++){
        if(x==1&&y!=n)x=n,y++;
        else if(y==n&&x!=1)y=1,x--;
        else if(x==1&&y==n)x++;
        else if(x!=1&&y!=n){
            if(!a[x-1][y+1])x--,y++;
            else x++;
        }
        a[x][y]=i;
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++)
            printf("%d ",a[i][j]);
        puts("");
    }
    return 0;
}
View Code

T2——信息传递——这题就是找一个最小环——至于做法,我用强连通分量做。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<stack>
using namespace std;
inline int read(){
    int t=1,num=0;char c=getchar();
    while(c>'9'||c<'0'){if(c=='-')t=-1;c=getchar();}
    while(c>='0'&&c<='9'){num=num*10+c-'0';c=getchar();}
    return num*t;
}
const int N=200010,inf=1e9;
int n,g[N],dfn[N],low[N],t=0,cnt=0,biao[N],ans=1e9;
stack<int> s;
void dfs(int x){
    dfn[x]=low[x]=++t;s.push(x);
    int y=g[x];
    if(!dfn[y]){dfs(y);low[x]=min(low[x],low[y]);}
    else if(!biao[y])low[x]=min(low[x],dfn[y]);
    if(low[x]==dfn[x]){
        int st=-1,tmp=0;cnt++;
        while(st!=x){
            st=s.top();s.pop();
            biao[st]=cnt;tmp++;
        }
        if(tmp!=1)ans=min(tmp,ans);
    }
}
int main()
{
    n=read();
    for(int i=1;i<=n;i++)g[i]=read();
    for(int i=1;i<=n;i++)
        if(!dfn[i])dfs(i);
    printf("%d\n",ans);
    return 0;
}
View Code

T3——斗地主——哎——看了半天不明白是怎么dfs+贪心的。

T4——跳石头——贪心+二分答案。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
inline int read(){
    int num=0,t=1;char c=getchar();
    while(c>'9'||c<'0'){if(c=='-')t=-1;c=getchar();}
    while(c<='9'&&c>='0'){num=(num<<1)+(num<<3)+c-'0';c=getchar();}
    return num*t;
}
int L,n,m,a[50010];
int check(int num){
    int la=0,cnt=0;
    for(int i=1;i<=n+1;i++)
        if(a[i]-la<num)cnt++;
        else la=a[i];
    return cnt;
}
int ef(){
    int l=1,r=L,mid,ans;
    while(l<=r){
        mid=(l+r)>>1;
        int tmp=check(mid);
        if(tmp<=m){ans=mid;l=mid+1;}
        else r=mid-1;
    }
    return ans;
}
int main()
{
    L=read();n=read();m=read();a[n+1]=L;
    for(int i=1;i<=n;i++)a[i]=read();
    printf("%d\n",ef());
    return 0;
}
View Code

T5——字串——动态规划!!

f[i][j][k][l]表示字符串a的前i个字符和字符串b的前j个字符用了k个子串,l=1表示a字符串的第i个字符必须被选出,l=0表示a字符串的第i个字符不能被选出。

为了优化空间,用滚动数组。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
inline int read(){
    int t=1,num=0;char c=getchar();
    while(c>'9'||c<'0'){if(c=='-')t=-1;c=getchar();}
    while(c>='0'&&c<='9'){num=num*10+c-'0';c=getchar();}
    return num*t;
}
#define min(a,b) (a<b?a:b)
const int N=1010,M=210,mod=1e9+7;
int n,m,ki,f[2][M][M][2];
char a[N],b[M];
int main()
{
    n=read();m=read();ki=read();
    scanf("%s%s",a+1,b+1);
    f[0][0][0][0]=f[1][0][0][0]=1;
    for(int i=1;i<=n;i++){
        int t=i&1;
        for(int j=1;j<=min(i,m);j++)
        for(int k=1;k<=min(j,ki);k++){
            f[t][j][k][1]=f[t][j][k][0]=0;
            f[t][j][k][0]=(f[t^1][j][k][0]+f[t^1][j][k][1])%mod;
            if(a[i]==b[j]){
                f[t][j][k][1]=(
                    f[t^1][j-1][k-1][1]+
                    f[t^1][j-1][k-1][0]
                )%mod;
                f[t][j][k][1]=(
                    f[t][j][k][1]+
                    f[t^1][j-1][k][1]
                )%mod;
            }
        }
    }
    printf("%d\n",(f[n&1][m][ki][0]+f[n&1][m][ki][1])%mod);
    return 0;
}
View Code

至于T6——不是很懂、、、、

本文由Yzyet编写,网址为www.cnblogs.com/Yzyet。非Yzyet同意,禁止转载,侵权者必究。

posted on 2017-09-10 10:26  Yzyet  阅读(268)  评论(0编辑  收藏  举报