ACM-ICPC 2016 大连赛区现场赛 A,D,F,B,J

题目链接:Wrestling Match

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

const int maxn=1e6+7;
int go[maxn],vis[maxn],col[maxn],bad[maxn];
vector<int >vec[maxn];
 
int dfs(int u){
    go[u]=1;
    for(int v:vec[u])    {
        if(!col[v] &&!bad[v] ){
            col[v]=col[u]^1;
            if(!dfs(v)) return 0;
        }
        else if(col[v]==col[u])  return 0;
    }
    return 1;
}
int main(){
    int n,m,x,y;
    while(~scanf("%d %d %d %d",&n,&m,&x,&y)){
        for(int i=0;i<=n;i++) vec[i].clear(),bad[i]=0,col[i]=0,go[i]=0,vis[i]=0;
        for(int i=1;i<=m;i++){
            int u,v;scanf("%d%d",&u,&v);
            vec[u].push_back(v);vec[v].push_back(u);
            vis[u]=vis[v]=1;
        }
        for(int i=1;i<=x;i++){
            int u;scanf("%d",&u);
            vis[u]=col[u]=1;
        }
        for(int i=1;i<=y;i++){
            int u;scanf("%d",&u);
            vis[u]=bad[u]=1;
            col[u]=0;
        }
        int cnt=0;
        for(int i=1;i<=n;i++) if(vis[i]) cnt++;
        if(cnt<n) printf("NO\n");
        else{
            for(int i=1;i<=n;i++){
                if(go[i]) continue;
                if(!dfs(i)) goto ed;
            }
            printf("YES\n");
            continue;
            ed:
                printf("NO\n");
           
        }
    }
    return 0;
}
 

题目链接:Regular Number

/**
 *
 *
 * 输出所给字符串中所有的能够表示的字符串。表示:每一行选择一个数字所形成的字符串 看样例。
 *
 *
 *
 * [样例输入]
 * 4
 * 3 0 9 7
 * 2 5 7
 * 2 2 5
 * 2 4 5
 * 09755420524
 *
 * [输出]:
 *
 * 9755
 * 7554
 * 0524
 * 
 * bitset
 *
 */

#include<bits/stdc++.h>

#define ll long long
using namespace std;

const int maxn = 1e3 + 7;
bitset<maxn> now[20];
bitset<maxn> tmp;

char ss[5100000];

int main() {
    for (int i = 0; i < 20; i++) now[i].reset();
    int t;
    scanf("%d", &t);
    for (int ii = 0; ii < t; ii++) {
        int n;
        scanf("%d", &n);
        for (int i = 0; i < n; i++) {
            int x;
            scanf("%d", &x);
            now[x].set(ii);
        }
    }
    scanf("%s", ss);
    tmp.reset();
    int sz = strlen(ss);
    for (int i = 0; i < sz; i++) {
        tmp = tmp << 1;
        tmp[0] = 1;
        tmp &= now[ss[i] - '0'];
        if (tmp[t - 1] == 1) {
            char zx=ss[i+1];
            ss[i+1]='\0';
            printf("%s\n",ss+i-t+1);
            ss[i+1]=zx;
//            for (int j = i - t + 1; j <= i; j++)
//                printf("%c", ss[j]);
//            printf("\n");血T
        }
    }
    return 0;
}

题目链接:A Simple Math Problem 

/**
 * x+y=a,lcm(x,y)=b;
 * 找 x,y;
 *  
 * i*(a-i)=b*gcd(a,a-i);
 * 枚举gcd就ok了
 *
 */

#include<bits/stdc++.h>

#define ll long long
using namespace std;

bool judge(ll x) {
    if (x < 0) return 0;
    ll xx = sqrt(x * 1.0);
    return xx * xx == x;
}

ll gcd(ll a,ll b){
    return b==0?a:gcd(b,a%b);
}

ll lcm(ll a,ll b){
    return  a/gcd(a,b)*b;
}

void solve(ll a, ll b) {
    vector<ll> vec;
    for (ll i = 1; i * i <= a; i++) {
        if (a % i == 0) {
            if (i * i != a) vec.push_back(i);
            vec.push_back(a / i);
        }
    }
    for (auto x:vec) {
        if (judge(a * a - 4 * b * x)) {
            ll zx = (ll) (sqrt(a * a * 1.0 - 4 * b * x));
            if(a>zx&&(a-zx)%2==0){
                if(lcm((a-zx)/2,a-(a-zx)/2)==b) {
                    printf("%lld %lld\n", (a - zx) / 2, a - (a - zx) / 2);
                    return;
                }
            }
            if((a+zx)%2==0&&(a+zx)<a*2) {
                if(lcm((a+zx)/2,a-(a+zx)/2)==b) {
                    printf("%lld %lld\n", (a + zx) / 2, a - (a + zx) / 2);
                    return;
                }
            }

        }
    }
    printf("No Solution\n");
}

int main() {
    ll a, b;
    while (~scanf("%lld %lld", &a, &b)) solve(a, b);
    return 0;
}

题目链接:Detachment

/*
 * [链接]:
 *
 * [题意]: 构造一个和为n的每个元素不相同的数组,使数组每一项的乘积最大。
 *
 *
 *
 * [分析]:显然均摊即可。
 *
 * [tricks]:
 *
 * [时间复杂度]:
 *
 * */


#include<bits/stdc++.h>

#define ll long long
using namespace std;

const ll mod = 1e9 + 7;
const ll maxn = 1e6 + 7;
ll inv_fac[maxn], fac[maxn];
ll zx[maxn];

ll ksm(ll a, ll b) {
    ll ans = 1;
    while (b) {
        if (b & 1) ans = ans * a % mod;
        b >>= 1;
        a = a * a % mod;
    }
    return ans;
}

int cnt = 0;

void init() {
    ll now = 0;
    for (ll i = 2; i < maxn; i++) {
        now += i;
        zx[cnt++] = now;
    }
    fac[1] = 1, fac[0] = 1, inv_fac[1] = inv_fac[0] = 1;
    for (ll i = 2; i < maxn; i++) fac[i] = fac[i - 1] * i % mod, inv_fac[i] = ksm(fac[i], mod - 2);
}

void solve(int T) {
    ll x;
    scanf("%lld", &x);
    if (x <= 1) {
        printf("%lld\n", x);
        return;
    }
    ll pos = lower_bound(zx, zx + cnt, x) - (zx);
    if (zx[pos] == x) {
        printf("%lld\n", fac[pos + 2]);
        return;
    }
    pos--;
    ll res = x - zx[pos];
    ll juntan = res / (pos + 1);
    ll shengyu = res % (pos + 1);
    ll zxr = pos + 2 + juntan + 1;
    ll zxl = zxr - shengyu + 1;
    ll ans = fac[zxr] * inv_fac[zxl - 1] % mod;
    ans = ans * fac[zxl - 2] % mod;
    ans = ans * inv_fac[juntan + 2 - 1] % mod;
    printf("%lld\n", ans);
}

int main() {

//    cout<<50<<endl;
//    for(int i=1;i<=50;i++) cout<<i<<endl;


//    printf("%lld\n",24*42*8);
    init();
    int T;
    scanf("%d", &T);
    while (T--) solve(T);
    return 0;
}

题目链接:Find Small A 

/*
 * [链接]:HDU5980
 *
 * [题意]:每个数字都可以表示成32位的二进制数,问每个数字表示成这样的数字每个字中存在多少个97;
 *
 * [分析]:
 *
 * [tricks]:
 *
 * [时间复杂度]:
 *
 * */


#include<bits/stdc++.h>

#define ll long long
using namespace std;

const ll mod = 1e9 + 7;
const ll maxn = 1e6 + 7;

ll a[maxn];

void solve(int T) {
    int n;
    cin >> n;
    int ans = 0;
    for (int i = 1; i <= n; i++) {
        int x;
        cin >> x;
        while (x) {
            ans += x % (1 << 8) == 97;
            x /= (1 << 8);
        }
    }
    cout << ans << endl;
}

int main() {
    int T = 1;
    while (T--) solve(T);
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值