首届全国中医药院校程序设计大赛

 √ 1537 序列的混乱程度 368 637
√  1538 随机数 264 357
 √··· 1539 完美序列 DP 13 62
 √··· 1540 第k大数 二分/经典 54 446
 √ 1541 选房子 305 341
  1542 Game 3 20
 √ 1543 Numbers 二进制/因子 76 334
 √··· 1544 Counting Words stringstream流类输入/字符串操作 250 465
 
1544-stringstream

 【1544分析】:(参考https://zhuanlan.zhihu.com/p/26063938)

  • 我们的思想是每次读取一行,然后再扫描该行的字符,同时计算结果。如果使用getchar( )边读边算,虽然代码较短,但容易写错,并且相对较难理解;
  • 可以把string作为流进行读写,定义在sstream头文件中。虽然string和sstream都很方便,但string很慢,sstream更慢,应谨慎使用
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2000 + 5;
const ll MOD = 1e9 + 7;

ll dp[maxn][maxn];

ll dfs(int x,int k) {
    if(k==1||x==1)
        return 1;
    if(dp[x][k]!=-1)
        return dp[x][k];
    ll rtn = 0;
    int lim = sqrt(x);
    for(int i=1;i<=lim;i++) if(x%i==0){
        rtn += dfs(i, k-1);
        if(i!=x/i) rtn += dfs(x/i,k-1);
    }
    return dp[x][k] = rtn%MOD;
}

int main() {
    int n, l, T;
    scanf("%d", &T);
    memset(dp,-1,sizeof(dp));
    while(T--) {
        scanf("%d%d",&n,&l);
        ll ans = 0;
        for(int i=1;i<=n;i++)
            (ans += dfs(i,l)) %= MOD;
        cout << ans << endl;
    }
    return 0;
} 
1539-记忆化
#include <stdio.h>  
#define MOD 1000000007  
int f[2010][2010]={0};  
  
void init()  
{  
    //长度i,当前j   
    for (int i=1;i<=2000;i++) f[1][i]=1;  
    for (int i=1;i<=2000;i++)  
        for (int j=1;j<=2000;j++)  
            for (int k=j;k<=2000;k+=j)  
                f[i+1][k]=(f[i+1][k]+f[i][j])%MOD;  
}  
  
  
int main()  
{  
    init();  
    int pp;scanf("%d",&pp);  
    while (pp--)  
    {  
        int n,m;scanf("%d%d",&n,&m);  
        long long ans=0;  
        for (int i=1;i<=n;i++)  
            ans=(ans+f[m][i])%MOD;  
        printf("%lld\n",ans);  
    }  
}  
1539-dp

 

#include<bits/stdc++.h>  
using namespace std;  
template<class T>inline T read(T&x)  
{  
    char c;  
    while((c=getchar())<=32)if(c==EOF)return 0;  
    bool ok=false;  
    if(c=='-')ok=true,c=getchar();  
    for(x=0; c>32; c=getchar())  
        x=x*10+c-'0';  
    if(ok)x=-x;  
    return 1;  
}  
template<class T> inline T read_(T&x,T&y)  
{  
    return read(x)&&read(y);  
}  
template<class T> inline T read__(T&x,T&y,T&z)  
{  
    return read(x)&&read(y)&&read(z);  
}  
template<class T> inline void write(T x)  
{  
    if(x<0)putchar('-'),x=-x;  
    if(x<10)putchar(x+'0');  
    else write(x/10),putchar(x%10+'0');  
}  
template<class T>inline void writeln(T x)  
{  
    write(x);  
    putchar('\n');  
}  

const int maxn=1e5+1;  
const double inf=999999999;  
#define lson (rt<<1),L,M  
#define rson (rt<<1|1),M+1,R  
#define M ((L+R)>>1)  
#define For(i,t,n) for(int i=(t);i<(n);i++)  
typedef long long  LL;  
typedef double DB;  
typedef pair<int,int> P;  
#define bug printf("---\n");  
#define mod  1000000007  
  
int a[maxn],b[maxn];  
int n,m,k;  
  
bool pan(LL num)  
{  
    int cnt=0;  
    for(int i=0;i<n;i++)  
        cnt+=m-(upper_bound(b,b+m,num/a[i])-b);//查找是否比num大的元素的个数  
   // printf("num=%lld  cnt=%d\n",num,cnt);  
    return cnt>k-1;  
}  
  
void slove()  
{  
    LL l=(LL)a[0]*b[0];  
    LL h=(LL)a[n-1]*b[m-1];//在最大最小值之间二分答案  
    while(l<=h)  
    {  
        LL mid=(LL)(l+h)/2;  
        if(pan(mid))  
            l=mid+1;  
        else  
            h=mid-1;  
    }  
    writeln(l);  
}  
  
int main()  
{  
    int T;  
    //freopen("in.txt","r",stdin);  
    read(T);  
    while(T--)  
    {  
        read__(n,m,k);  
        For(i,0,n)read(a[i]);  
        For(i,0,m)read(b[i]);  
        sort(a,a+n);  
        sort(b,b+m);  
        slove();  
    }  
    return 0;  
}  
1540-二分

 

#include<cstdio>
using namespace std;
int a[100];
int check(int n)//判断二进制位当中有没有相等的
{
    int r;
    int i=0;
    while(n)//n右移一位相当于n/2
    {
        r=n&1;//如果n的二进制位当中是1的则还是1如果是0的则变成0了
        if(r==a[i++])
            return 1;
            n>>=1;
    }
    return 0;
}
int main()
{
    int t,i;
    long long n,m,count;
    scanf("%d",&t);
    while(t--)
    {    count=0;
        scanf("%lld",&n);
        m=n;
        for(i=0;n!=0;i++)
        {
            a[i]=n&1;//把n的二进制位写入
            n=n>>1;
        }
        for(i=1;i*i<=m;i++)
        {
            if(m%i==0)
            {
                if(check(i))
                    count++;//这个是检测因子的好办法了省时间
                if(check(m/i)&&(i*i!=m))
                    count++;
            }
        }
        printf("%lld\n",count);
    }
    return 0;
}
1543-二进制

 

posted @ 2017-09-22 18:21  Roni_i  阅读(515)  评论(0编辑  收藏  举报