CSU-ACM2016暑假集训比赛6

A - A
Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u
Submit

Status

Practice

CodeForces 538B
Description
A number is called quasibinary if its decimal representation contains only digits 0 or 1. For example, numbers 0, 1, 101, 110011 — are quasibinary and numbers 2, 12, 900 are not.

You are given a positive integer n. Represent it as a sum of minimum number of quasibinary numbers.

Input
The first line contains a single integer n (1 ≤ n ≤ 106).

Output
In the first line print a single integer k — the minimum number of numbers in the representation of number n as a sum of quasibinary numbers.

In the second line print k numbers — the elements of the sum. All these numbers should be quasibinary according to the definition above, their sum should equal n. Do not have to print the leading zeroes in the numbers. The order of numbers doesn’t matter. If there are multiple possible representations, you are allowed to print any of them.

Sample Input
Input
9
Output
9
1 1 1 1 1 1 1 1 1
Input
32
Output
3
10 11 11


#include<stdio.h>
#include<string>
#include<cstring>
#include<queue>
#include<algorithm>
#include<functional>
#include<vector>
#include<iomanip>
#include<math.h>
#include<iostream>
#include<sstream>
#include<set>
using namespace std;
int main()
{
    int ans=0;
    string s,temp;
    cin>>s;
    int a[12];
    for (int i=0; i<(int)s.length(); i++)
    {
        a[i]=(int)(s[i]-'0');
        ans=max(ans,a[i]);
    }
    cout<<ans<<endl;
    for (int i=1; i<=ans; i++)
    {
        for (int j=0; j<(int)s.length(); j++)
        {
            temp.resize(s.length());
            if (a[j]>0)
            {
                temp[j]='1';
                a[j]--;
            }
            else
            {
                temp[j]='0';
            }
        }
        for (int i=0;i<temp.length();i++)
        {
            if (temp[i]=='0')
            {
                temp.erase(i,1);
                i--;
            }
            else
                break;
        }
        cout<<temp<<' ';
    }
    return 0;
}

B - B
Time Limit:3000MS Memory Limit:0KB 64bit IO Format:%lld & %llu
Submit

Status

Practice

UVA 10003

uDebug
Description

You have to cut a wood stick into pieces. The most affordable company, The Analog Cutting Machinery,
Inc. (ACM), charges money according to the length of the stick being cut. Their procedure of work
requires that they only make one cut at a time.
It is easy to notice that different selections in the order of cutting can led to different prices. For
example, consider a stick of length 10 meters that has to be cut at 2, 4 and 7 meters from one end.
There are several choices. One can be cutting first at 2, then at 4, then at 7. This leads to a price
of 10 + 8 + 6 = 24 because the first stick was of 10 meters, the resulting of 8 and the last one of 6.
Another choice could be cutting at 4, then at 2, then at 7. This would lead to a price of 10 + 4 + 6 =
20, which is a better price.
Your boss trusts your computer abilities to find out the minimum cost for cutting a given stick.
Input
The input will consist of several input cases. The first line of each test case will contain a positive
number l that represents the length of the stick to be cut. You can assume l < 1000. The next line will
contain the number n (n < 50) of cuts to be made.
The next line consists of n positive numbers ci (0 < ci < l) representing the places where the cuts
have to be done, given in strictly increasing order.
An input case with l = 0 will represent the end of the input.
Output
You have to print the cost of the optimal solution of the cutting problem, that is the minimum cost of
cutting the given stick. Format the output as shown below.
Sample Input
100
3
25 50 75
10
4
4 5 7 8
0
Sample Output
The minimum cutting is 200.
The minimum cutting is 22.


B: 区间DP

#include<stdio.h>
#include<string>
#include<cstring>
#include<queue>
#include<algorithm>
#include<functional>
#include<vector>
#include<iomanip>
#include<math.h>
#include<iostream>
#include<sstream>
#include<set>
using namespace std;
const int MAX=55;
const int INF=99999999;
int L,N,A[MAX],F[MAX][MAX];  //F[i][j] (i,j)区间内的最小消耗
int main()
{
    while(cin>>L&&L&&cin>>N)
    {
        for (int i=1;i<=N;i++)
            cin>>A[i];
        A[0]=0;A[N+1]=L;
        memset(F,0,sizeof(F));
        for (int l=3;l<=N+2;l++)
        {
            for (int i=0;i<=N+2-l;i++)
            {
                int j=i+l-1;
                F[i][j]=INF;
                for (int k=i+1;k<j;k++)
                {
                    F[i][j]=min(F[i][j],F[i][k]+F[k][j]+A[j]-A[i]);
                }
            }
        }
        cout<<"The minimum cutting is "<<F[0][N+1]<<"."<<endl;
    }
    return 0;
}

C - C
Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u
Submit

Status

Practice

HDU 3466
Description
Recently, iSea went to an ancient country. For such a long time, it was the most wealthy and powerful kingdom in the world. As a result, the people in this country are still very proud even if their nation hasn’t been so wealthy any more.
The merchants were the most typical, each of them only sold exactly one item, the price was Pi, but they would refuse to make a trade with you if your money were less than Qi, and iSea evaluated every item a value Vi.
If he had M units of money, what’s the maximum value iSea could get?

Input
There are several test cases in the input.

Each test case begin with two integers N, M (1 ≤ N ≤ 500, 1 ≤ M ≤ 5000), indicating the items’ number and the initial money.
Then N lines follow, each line contains three numbers Pi, Qi and Vi (1 ≤ Pi ≤ Qi ≤ 100, 1 ≤ Vi ≤ 1000), their meaning is in the description.

The input terminates by end of file marker.

Output
For each test case, output one integer, indicating maximum value iSea could get.

Sample Input
2 10
10 15 10
5 10 5
3 10
5 10 5
3 5 6
2 7 3
Sample Output
5
11



C:
要保证动归方程无后效性
j-p[i]一定要比j先算
算i时,最小能算到q[i]-p[i]
因此以q[i]-p[i]从小到大排序

#include<stdio.h>
#include<string>
#include<cstring>
#include<queue>
#include<algorithm>
#include<functional>
#include<vector>
#include<iomanip>
#include<math.h>
#include<iostream>
#include<sstream>
#include<set>
using namespace std;
struct item
{
    int P,Q,V;
};
item items[505];
int N,M,F[5005];
bool cmp(item a,item b)
{
    return (a.Q-a.P)<(b.Q-b.P);
}
void ZeroOnePack(int Pi,int Qi,int Vi)
{
    for (int i=M;i>=Qi;i--)
        F[i]=max(F[i],F[i-Pi]+Vi);
}
int main()
{
    while (cin>>N>>M)
    {
        memset(F,0,sizeof(F));
        for (int i=0;i<N;i++)
            cin>>items[i].P>>items[i].Q>>items[i].V;
        sort(items,items+N,cmp);
        for (int i=0;i<N;i++)
            ZeroOnePack(items[i].P,items[i].Q,items[i].V);
        cout<<F[M]<<endl;
    }
    return 0;
}

D - D
Time Limit:1000MS Memory Limit:131072KB 64bit IO Format:%lld & %llu
Submit

Status

Practice

CSU 1660
Description
A simple cycle is a closed simple path, with no other repeated vertices or edges other than the starting and ending vertices. The length of a cycle is the number of vertices on it. Given an undirected graph G(V, E), you are to detect whether it contains a simple cycle of length K. To make the problem easier, we only consider cases with small K here.
Input
There are multiple test cases.
The first line will contain a positive integer T (T ≤ 10) meaning the number of test cases.
For each test case, the first line contains three positive integers N, M and K ( N ≤ 50, M ≤ 500, 3 ≤ K ≤ 7). N is the number of vertices of the graph, M is the number of edges and K is the length of the cycle desired. Next follow M lines, each line contains two integers A and B, describing an undirected edge AB of the graph. Vertices are numbered from 0 to N-1.
Output
For each test case, you should output “YES” in one line if there is a cycle of length K in the given graph, otherwise output “NO”.
Sample Input
2
6 8 4
0 1
1 2
2 0
3 4
4 5
5 3
1 3
2 4
4 4 3
0 1
1 2
2 3
3 0
Sample Output
YES
NO


D:dfs 不要瞎几把回复状态..超时了好几次


#include<stdio.h>
#include<string>
#include<cstring>
#include<queue>
#include<algorithm>
#include<functional>
#include<vector>
#include<iomanip>
#include<math.h>
#include<iostream>
#include<sstream>
#include<set>
using namespace std;
int T,N,M,K;
vector<int> graph[55];
int mark[55];
bool findCycle;
void dfs(int prev,int now,int cnt)
{
    if (findCycle) return;
    //cout<<prev<<"->"<<now<<" : "<<cnt<<endl;
    if (mark[now]!=-1)
    {
        if (cnt-mark[now]==K)
        {
            findCycle=true;
            return;
        }
    }
    else
    {
        mark[now]=cnt;
        for (int i=0; i<(int)graph[now].size(); i++)
        {
            if (graph[now][i]!=prev)
            {
                dfs(now,graph[now][i],cnt+1);
                if (findCycle) break;
            }
        }
    }
}
int main()
{
    int a,b;
    cin>>T;
    while (T--)
    {
        for (int i=0; i<55; i++)
            graph[i].clear();
        findCycle=false;
        cin>>N>>M>>K;
        for (int i=0; i<M; i++)
        {
            cin>>a>>b;
            graph[a].push_back(b);
            graph[b].push_back(a);
        }
        for (int i=0; i<N; i++)
        {
            //cout<<"第"<<i<<"次dfs:"<<endl;
            memset(mark,-1,sizeof(mark));
            dfs(i,i,0);
            if (findCycle) break;
        }
        if (findCycle) cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }
    return 0;
}

E - E
Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u
Submit

Status

Practice

CodeForces 75C
Description
Well, here is another math class task. In mathematics, GCD is the greatest common divisor, and it’s an easy task to calculate the GCD between two positive integers.
A common divisor for two positive numbers is a number which both numbers are divisible by.
But your teacher wants to give you a harder task, in this task you have to find the greatest common divisor d between two integers a and b that is in a given range from low to high (inclusive), i.e. low ≤ d ≤ high. It is possible that there is no common divisor in the given range.
You will be given the two integers a and b, then n queries. Each query is a range from low to high and you have to answer each query.
Input
The first line contains two integers a and b, the two integers as described above (1 ≤ a, b ≤ 109). The second line contains one integer n, the number of queries (1 ≤ n ≤ 104). Then n lines follow, each line contains one query consisting of two integers, low and high (1 ≤ low ≤ high ≤ 109).
Output
Print n lines. The i-th of them should contain the result of the i-th query in the input. If there is no common divisor in the given range for any query, you should print -1 as a result for this query.
Sample Input
Input
9 27
3
1 5
10 11
9 11
Output
3
-1
9



E:  找出a和b的所有约数 再用二分搜索

#include<stdio.h>
#include<string>
#include<cstring>
#include<queue>
#include<algorithm>
#include<functional>
#include<vector>
#include<iomanip>
#include<math.h>
#include<iostream>
#include<sstream>
#include<set>
using namespace std;
int a,b,n,low,high;
vector<int> gcd;
vector<int>::iterator it;
int main()
{
    while (cin>>a>>b>>n)
    {
        gcd.clear();
        int c=__gcd(a,b);
        for (int i=1; i<=sqrt(c)+1; i++)
        {
            if (c%i==0)
            {
                gcd.push_back(i);
                gcd.push_back(c/i);
            }
        }
        sort(gcd.begin(),gcd.end());
        unique(gcd.begin(),gcd.end());
        for (int i=1; i<=n; i++)
        {
            cin>>low>>high;
            it=upper_bound(gcd.begin(),gcd.end(),high);
            if (*(it-1)>=low)
                cout<<*(it-1)<<endl;
            else
                cout<<-1<<endl;
        }
    }
    return 0;
}

F - F
Time Limit:3000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u
Submit

Status

Practice

CodeForces 702B
Description
You are given n integers a1, a2, …, an. Find the number of pairs of indexes i, j (i < j) that ai + aj is a power of 2 (i. e. some integer x exists so that ai + aj = 2x).
Input
The first line contains the single positive integer n (1 ≤ n ≤ 105) — the number of integers.
The second line contains n positive integers a1, a2, …, an (1 ≤ ai ≤ 109).
Output
Print the number of pairs of indexes i, j (i < j) that ai + aj is a power of 2.
Sample Input
Input
4
7 3 2 1
Output
2
Input
3
1 1 1
Output
3
Hint
In the first example the following pairs of indexes include in answer: (1, 4) and (2, 4).
In the second example all pairs of indexes (i, j) (where i < j) include in answer.



F: 二分搜索 stl

upper_bound(A+i+1,A+N,temp)-lower_bound(A+i+1,A+N,temp) 得出从A[i+1]开始到A[N-1]的等于temp的值的个数

#include<stdio.h>
#include<string>
#include<cstring>
#include<queue>
#include<algorithm>
#include<functional>
#include<vector>
#include<iomanip>
#include<math.h>
#include<iostream>
#include<sstream>
#include<set>
using namespace std;
typedef long long ll;
const ll MAX=1111111111;
ll N,A[100005];
vector<ll> power;
vector<ll>::iterator it;
int main()
{
    for (ll i=1;i<=MAX;i*=2)
    {
        power.push_back(i);
    }
    while (cin>>N)
    {
        ll ans=0;
        for (ll i=0;i<N;i++)
            cin>>A[i];
        sort(A,A+N);
        for (ll i=0;i<N;i++)
        {
            for (int j=0;j<(int)power.size();j++)
            {
                ll temp=power[j]-A[i];
                if (temp>0)
                    ans+=upper_bound(A+i+1,A+N,temp)-lower_bound(A+i+1,A+N,temp);
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值