Codeforces_793

A.找最小的数,看每个数跟它的差是否被k整除。

#include<bits/stdc++.h>
#define MOD 1000000007
using namespace std;

int n,cnt[100005] = {0},ans[100005],two[100005];

int main()
{
    ios::sync_with_stdio(false);
    cin >> n;
    while(n--)
    {
        int x;
        cin >> x;
        for(int i = 1;i*i <= x;i++)
        {
            if(x%i == 0)
            {
                cnt[i]++;
                if(i*i != x)    cnt[x/i]++;
            }
        }
    }
    two[0] = 1;
    for(int i = 1;i <= 100000;i++)  two[i] = two[i-1]*2%MOD;
    for(int i = 1;i <= 100000;i++)  ans[i] = two[cnt[i]]-1;
    for(int i = 100000;i >= 1;i--)
    {
        for(int j = i*2;j <= 100000;j += i) ans[i] = (ans[i]-ans[j]+MOD)%MOD;
    }
    cout << ans[1] << endl;
    return 0;
}
View Code

B.直接dfs记录方向和转弯次数,不做其他剪枝就能过。

#include<bits/stdc++.h>
#define MOD 1000000007
using namespace std;

int n,m,vis[1005][1005][2] = {0},x1,Y1,flag = 0;
int dx[4] = {-1,0,1,0};
int dy[4] = {0,-1,0,1};
string a[1005];

void dfs(int x,int y,int d,int cnt)
{
    if(cnt > 2) return;
    if(flag)    return;
    if(a[x][y] == 'T')  flag = 1;
    if(d != -1) vis[x][y][d] = 1;
    for(int i = 0;i < 4;i++)
    {
        if((i+2)%4 == d)  continue;
        int xx = x+dx[i],yy = y+dy[i];
        if(xx < 1 || xx > n || yy < 1 || yy > m || a[xx][yy] == '*')  continue;
        if(vis[xx][yy][i])  continue;
        dfs(xx,yy,i,cnt+(i != d));
    }
}
int main()
{
    ios::sync_with_stdio(false);
    cin >> n >> m;
    for(int i = 1;i <= n;i++)
    {
        cin >> a[i];
        a[i] = " "+a[i];
    }
    for(int i = 1;i <= n;i++)
    {
        for(int j = 1;j <= m;j++)
        {
            if(a[i][j] == 'S')  x1 = i,Y1 = j;
        }
    }
    dfs(x1,Y1,-1,-1);
    if(flag)    cout << "YES" << endl;
    else    cout << "NO" << endl;
    return 0;
}
View Code

C.遍历每只老鼠,一次次缩小时间区间,最后考虑可能性,注意速率为0和边缘情况。

#include<bits/stdc++.h>
#define MOD 1000000007
using namespace std;

int n,flag = 0;
double ansl = 0,ansr = 1e9;

void f(int x,int v,int l,int r)
{
    if(v == 0 && (x <= l || x >= r))
    {
        flag = 1;
        return;
    }
    double t = 1.0*(l-x)/v,tt = 1.0*(r-x)/v;
    ansl = max(ansl,min(t,tt));
    ansr = min(ansr,max(t,tt));
}

int main()
{
    ios::sync_with_stdio(false);
    cin >> n;
    int x1,y1,x2,y2;
    cin >> x1 >> y1 >> x2 >> y2;

    for(int i = 1;i <= n;i++)
    {
        int a,b,c,d;
        cin >> a >> b >> c >> d;
        f(a,c,x1,x2);
        f(b,d,y1,y2);
    }
    if(flag == 0 && ansl < ansr)    cout << fixed << setprecision(10) << ansl << endl;
    else    cout << -1 << endl;
    return 0;
}
View Code

 D.暴力每一个起点,每次移动,更新区间,记忆化一下,dp[i][j][k][l]表示当前在i,可行区间(j,k),已经经过l个点。

#include<bits/stdc++.h>
using namespace std;

int n,m,k,g[85][85],dp[85][85][85][85];

int dfs(int now,int l,int r,int cnt)
{
    int &ans = dp[now][l][r][cnt];
    if(ans != -1)    return ans;
    if(cnt == k)
    {
        ans = 0;
        return 0;
    }
    ans = 1e9;
    for(int i = l+1;i < r;i++)
    {
        if(g[now][i] == 1e9)  continue;
        int x = l,y = r;
        if(now < i) x = now;
        else    y = now;
        ans = min(ans,g[now][i]+dfs(i,x,y,cnt+1));
    }
    return ans;
}
int main()
{
    ios::sync_with_stdio(false);
    cin >> n >> k >> m;
    for(int i = 1;i <= n;i++)
    {
        for(int j = 1;j <= n;j++)   g[i][j] = 1e9;
    }
    memset(dp,-1,sizeof(dp));
    for(int i = 1;i <= m;i++)
    {
        int x,y,z;
        cin >> x >> y >> z;
        g[x][y] = min(g[x][y],z);
    }
    int ans = 1e9;
    for(int i = 1;i <= n;i++)   ans = min(ans,dfs(i,0,n+1,1));
    if(ans == 1e9)  cout << -1 << endl;
    else    cout << ans << endl;
    return 0;
}
View Code

 

posted @ 2017-05-02 06:28  zzzzzzzzhu  阅读(195)  评论(0编辑  收藏  举报