2019/5/15 写题总结

今天目标10题达成。ε=ε=ε=(~ ̄▽ ̄)~ 。

总结一下今天:

1: Strictly Positive Matrix

代码:

#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const int _inf = 0xc0c0c0c0;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL _INF = 0xc0c0c0c0c0c0c0c0;
const LL mod =  (int)1e9+7;
const int N = 2e3 + 10;
const int M = N * N;
int head[N], nt[M], to[M], tot;
void add(int u, int v){
    to[tot] = v;
    nt[tot] = head[u];
    head[u] = tot++;
}
int belong[N], dfn[N], low[N], now_time, scc_cnt;
stack<int> s;
void dfs(int u){
    dfn[u] = low[u] = ++now_time;
    s.push(u);
    for(int i = head[u]; ~i; i = nt[i]){
        if(!dfn[to[i]]) dfs(to[i]);
        if(!belong[to[i]]) low[u] = min(low[u], low[to[i]]);
    }
    if(dfn[u] == low[u]){
        ++scc_cnt;
        int now;
        while(1){
            now = s.top(); s.pop();
            belong[now] = scc_cnt;
            if(now == u) break;
        }
    }
}
void scc(int n){
    now_time = scc_cnt = 0;
    for(int i = 1; i <= n; ++i)
        if(!belong[i]) dfs(i);
}
int main(){
    memset(head, -1, sizeof(head));
    int n, t;
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i){
        for(int j = 1; j <= n; ++j){
            scanf("%d", &t);
            if(t) add(i, j);
        }
    }
    scc(n);
//    cout << "?" << endl;
    if(scc_cnt ^ 1) puts("NO");
    else puts("YES");
    return 0;
}
View Code

*重点是将dp[i][j]看作 i -> j 之间存在有一条边, 如果dp[i][j] 本来没有边, 那么会通过别的点走过来。

所以跑一边scc之后,判断一下是不是一个强连通的点。

 

2.Substitutes in Number

代码:

#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const int _inf = 0xc0c0c0c0;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL _INF = 0xc0c0c0c0c0c0c0c0;
const LL mod =  (int)1e9+7;
const int N = 1e5 + 100;
char s[N];
string str[N];
LL dp[15], base[15];
void solve(string & sstr){
    int m = sstr[0] - '0';
    int len = sstr.size();
    LL tmp_base = 1; LL tmp_yu = 0;
    for(int i = 3; i < len; ++i){
        int id = sstr[i] - '0';
        tmp_base = (tmp_base * base[id]) % mod;
        tmp_yu = (tmp_yu * base[id] + dp[id]) % mod;
    }
    dp[m] = tmp_yu, base[m] = tmp_base;
//    cout << m << ' ' << dp[m] << ' '  << base[m] << endl;
}
int main(){
    scanf("%s", s+1);
    int n;
    scanf("%d", &n);
    for(int i = 0; i < 10; ++i)
        dp[i] = i, base[i] = 10;
    for(int i = 1; i <= n; ++i){
        cin >> str[i];
    }
    for(int i = n; i >= 1; --i){
        solve(str[i]);
    }
    int m = strlen(s+1);
    LL ans = 0;
    for(int i = 1; i <= m; ++i){
        int id = s[i] - '0';
        ans = (ans * base[id] + dp[id]) % mod;
    }
    cout << ans << endl;
    return 0;
}
View Code

* 将每个0~9的字符所对应的值和长度表现出来就好了。

 

3. Sereja and the Arrangement of Numbers

代码:

#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const int _inf = 0xc0c0c0c0;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL _INF = 0xc0c0c0c0c0c0c0c0;
const LL mod =  (int)1e9+7;
const int N = 1e5 + 100;
int n, m;
int a[N], b[N];
LL dp[N];
int main(){
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= m; ++i){
        scanf("%d%d", &a[i], &b[i]);
        if(i&1) dp[i] = 1 + i * (i - 1ll) / 2;
        else dp[i] = 1 + i * (i-1ll)/2 + i/2 - 1;
    }
    int k = m;
    while(dp[k] > n) --k;
    sort(b+1, b+1+m, greater<int>());
    LL ans = 0;
    for(int i = 1; i <= k; ++i)
        ans += b[i];
    cout << ans << endl;
    return 0;
}
View Code

* 重点是将点和拓扑图挂钩。

 

6. Andrew and Taxi

 

代码:

#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const int _inf = 0xc0c0c0c0;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL _INF = 0xc0c0c0c0c0c0c0c0;
const LL mod =  (int)1e9+7;
const int N = 1e5 + 100;
int u[N], v[N], c[N];
vector<int> vc[N];
int n, m;
int ind[N], top[N];
bool check(int mid){
    for(int i = 1; i <= n; ++i){
        vc[i].clear(); ind[i] = 0;
    }
    for(int i = 1; i <= m; ++i){
        if(c[i] > mid){
            vc[u[i]].pb(v[i]);
            ind[v[i]]++;
        }
    }
    queue<int> q;
    int m = 0;
    for(int i = 1; i <= n; ++i){
        if(!ind[i]) q.push(i);
    }
    while(!q.empty()){
        int x = q.front();
        q.pop();
        top[x] = ++m;
        for(int v : vc[x]){
            ind[v]--;
            if(!ind[v]) q.push(v);
        }
    }
    for(int i = 1; i <= n; ++i){
        if(ind[i]) return false;
    }
    return true;
}
vector<int> ans;
int main(){

    scanf("%d%d", &n, &m);
    for(int i = 1; i <= m; ++i)
        scanf("%d%d%d", &u[i], &v[i], &c[i]);
    int L = 0, R = 1e9 + 100;
    while(L <= R){
        int mid = L+R >> 1;
        if(!check(mid)) L = mid + 1;
        else R = mid - 1;
    }

    check(L);
    int tt = 0;
    for(int i = 1; i <= m; ++i){
        if(c[i] <= L) {
            if(top[u[i]] > top[v[i]]){
                ans.pb(i);
            }
        }
    }
    printf("%d %d\n", L, ans.size());
    for(int id : ans){
        printf("%d ", id);
    }
    return 0;
}
View Code

* 还是题目没读仔细, 读仔细应该能想到二分。

* 然后不知道 二分完之后,怎么确定小的边。  -> 用top去维护出边的方向, 这样就会存在环了。

 

 

其他:

1. 读题还是有点问题, 不知道怎么说, 还是会漏掉比较重要的条件。

2. 空间还是有时候没注意, 或者说下意识的就以为够了。

3. 思路在自己想的时候想好了, 然后写的忘了, 然后补完之后,特殊的小情况忘了改。。。。

 

posted @ 2019-05-15 22:59  Schenker  阅读(146)  评论(0编辑  收藏  举报