【LDU】2017级课后练习题#1

A-活动安排问题

https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1428

有若干个活动,第i个开始时间和结束时间是[Si,fi),同一个教室安排的活动之间不能交叠,求要安排所有活动,最少需要几个教室? 
Input
第一行一个正整数n (n <= 10000)代表活动的个数。
第二行到第(n + 1)行包含n个开始时间和结束时间。
开始时间严格小于结束时间,并且时间都是非负整数,小于1000000000
Output
一行包含一个整数表示最少教室的个数。
Input示例
3
1 2
3 4
2 9
Output示例
2

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long ll;
struct node{
   ll si,fi;
}a[10050];
int cmp(node x,node y)
{
   if(x.si==y.si)
        return x.fi<y.fi;
    return x.si<y.si;
}
int main()
{
    int n,i,j,k,T,count=0,max=0;
    scanf("%d",&n);
    for(i=0;i<n;i++)
    {
      scanf("%lld%lld",&a[i].si,&a[i].fi);
    }
    sort(a,a+n,cmp);
    for(i=0;i<n;i++)
    {
       count=1;
       for(j=i-1;j>=0;j--)
       {
         if(a[i].si<a[j].fi)
         {count++;}
       }
       if(count>max)
       max=count;
    }
    printf("%d\n",max);
    return 0;
}


B、完美字符串

https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1182

约翰认为字符串的完美度等于它里面所有字母的完美度之和。每个字母的完美度可以由你来分配,不同字母的完美度不同,分别对应一个1-26之间的整数。
约翰不在乎字母大小写。(也就是说字母F和f)的完美度相同。给定一个字符串,输出它的最大可能的完美度。例如:dad,你可以将26分配给d,25分配给a,这样整个字符串完美度为77。
Input
输入一个字符串S(S的长度 <= 10000),S中没有除字母外的其他字符。
Output
由你将1-26分配给不同的字母,使得字符串S的完美度最大,输出这个完美度。
Input示例
dad
Output示例
77
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define N 10050
using namespace std;
int main()
{
     int i,j,k,b[27],sum=0;
     char a[N];
     scanf("%s",a);
     for(i=0;i<strlen(a);i++)
     {
        b[a[i]>'Z'?(a[i]-'a'+1):(a[i]-'A'+1)]++;
     }
     sort(b,b+27);
     for(i=26;i>=1;i--)
     {
        sum+=b[i]*i;
     }
     printf("%d\n",sum);
     return 0;


}

C、无向图最小生成树

https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1212

N个点M条边的无向连通图,每条边有一个权值,求该图的最小生成树。
Input
第1行:2个数N,M中间用空格分隔,N为点的数量,M为边的数量。(2 <= N <= 1000, 1 <= M <= 50000)
第2 - M + 1行:每行3个数S E W,分别表示M条边的2个顶点及权值。(1 <= S, E <= N,1 <= W <= 10000)
Output
输出最小生成树的所有边的权值之和。
Input示例
9 14
1 2 4
2 3 8
3 4 7
4 5 9
5 6 10
6 7 2
7 8 1
8 9 7
2 8 11
3 9 2
7 9 6
3 6 4
4 6 14
1 8 8
Output示例
37


#include<stdio.h>
#include<string.h>
int G[1001][1001],vis[1001],dis[1001];
const int inf=0x3f3f3f3f;
int n,m;
void prim()
{
     int i,j,k,minz,ans=0;
     memset(vis,0,sizeof(vis));
     for(i=1;i<=n;i++)
     {
         dis[i]=G[1][i];
     }
     vis[1]=1;
     for(i=2;i<=n;i++)
     {
         k=0;minz=inf;
         for(j=1;j<=n;j++)
         {
             if(!vis[j]&&dis[j]<minz)
             {
                  minz=dis[j];
                  k=j;
             }
         }
         if(k==0)
         {
            break;
         }
         vis[k]=1;
         ans+=minz;
         for(j=1;j<=n;j++)
         {
             if(!vis[j]&&dis[j]>G[k][j])
             {
                  dis[j]=G[k][j];
             }
         }
     }
     printf("%d\n",ans);
     return ;
}
int main()
{
      int i,j,k,x,y,z;
      memset(G,inf,sizeof(G));
      while(~scanf("%d%d",&n,&m))
      {
           for(i=0;i<m;i++)
           {
              scanf("%d%d%d",&x,&y,&z);
              if(G[x][y]>z)
             {
                 G[x][y]=G[y][x]=z;
             }
           }
           prim();
      }
      return 0;
}


D、不重叠的线段

https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1133

X轴上有N条线段,每条线段有1个起点S和终点E。最多能够选出多少条互不重叠的线段。(注:起点或终点重叠,不算重叠)。
例如:[1 5][2 3][3 6],可以选[2 3][3 6],这2条线段互不重叠。
Input
第1行:1个数N,线段的数量(2 <= N <= 10000)
第2 - N + 1行:每行2个数,线段的起点和终点(-10^9 <= S,E <= 10^9)
Output
输出最多可以选择的线段数量。
Input示例
3
1 5
2 3
3 6
Output示例
2


#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long ll;
struct node
{
    ll r,l;
}a[10050];
bool cmp(node x,node y)
{
    if(x.l==y.l)
         return x.r<y.r;
     return x.r<y.r;
}
int main()
{
     int i,n,j;
     while(~scanf("%d",&n))
     {
         for(i=0;i<n;i++)
         {
             scanf("%lld%lld",&a[i].l,&a[i].r);
         }
         sort(a,a+n,cmp);
         node p=a[0];
         int sum=1;
         for(i=1;i<n;i++)
         {
             if(p.r<=a[i].l)
             {
                 sum++;
                 p=a[i];
             }
         }
         printf("%d\n",sum);
     }
     return 0;
}


E、 走格子

https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1344

有编号1-n的n个格子,机器人从1号格子顺序向后走,一直走到n号格子,并需要从n号格子走出去。机器人有一个初始能量,每个格子对应一个整数A[i],表示这个格子的能量值。如果A[i] > 0,机器人走到这个格子能够获取A[i]个能量,如果A[i] < 0,走到这个格子需要消耗相应的能量,如果机器人的能量 < 0,就无法继续前进了。问机器人最少需要有多少初始能量,才能完成整个旅程。

例如:n = 5。{1,-2,-1,3,4} 最少需要2个初始能量,才能从1号走到5号格子。途中的能量变化如下3 1 0 3 7。
Input
第1行:1个数n,表示格子的数量。(1 <= n <= 50000)
第2 - n + 1行:每行1个数A[i],表示格子里的能量值(-1000000000 <= A[i] <= 1000000000)
Output
输出1个数,对应从1走到n最少需要多少初始能量。
Input示例
5
1
-2
-1
3
4
Output示例
2


#include<stdio.h>
#include<math.h>
typedef long long ll;
int main()
{
     ll i,x,n,sum=0,minz=1e18;
     scanf("%lld",&n);
     for(i=0;i<n;i++)
     {
         scanf("%lld",&x);
         sum+=x;
         if(minz>sum)
         {
            minz=sum;
         }
     }
     printf("%.0lf\n",fabs(minz));
     return 0;
}


F-pie-二分

http://acm.hdu.edu.cn/showproblem.php?pid=1969

Problem Description
My birthday is coming up and traditionally I'm serving pie. Not just one pie, no, I have a number N of them, of various tastes and of various sizes. F of my friends are coming to my party and each of them gets a piece of pie. This should be one piece of one pie, not several small pieces since that looks messy. This piece can be one whole pie though.

My friends are very annoying and if one of them gets a bigger piece than the others, they start complaining. Therefore all of them should get equally sized (but not necessarily equally shaped) pieces, even if this leads to some pie getting spoiled (which is better than spoiling the party). Of course, I want a piece of pie for myself too, and that piece should also be of the same size. 

What is the largest possible piece size all of us can get? All the pies are cylindrical in shape and they all have the same height 1, but the radii of the pies can be different.
 

Input
One line with a positive integer: the number of test cases. Then for each test case:
---One line with two integers N and F with 1 <= N, F <= 10 000: the number of pies and the number of friends.
---One line with N integers ri with 1 <= ri <= 10 000: the radii of the pies.
 

Output
For each test case, output one line with the largest possible volume V such that me and my friends can all get a pie piece of size V. The answer should be given as a floating point number with an absolute error of at most 10^(-3).
 

Sample Input
  
  
3 3 3 4 3 3 1 24 5 10 5 1 4 2 3 4 5 6 5 4 2
 

Sample Output
  
  
25.1327 3.1416 50.2655

#include<stdio.h>
#include<string.h>
#include<math.h>
const double pi=acos(-1);
const double EPS=1e-5;
double v[10050],V;
int n,f;
int judge(double s)
{
     int i,sum=0;
     for(i=0;i<n;i++)
     {
        sum+=(floor(v[i]/s));
     }
     return sum;
}
int main()
{
     int t,i;
     scanf("%d",&t);
          while(t--)
          {
               double r;
               scanf("%d%d",&n,&f);
               f+=1;V=0;
               for(i=0;i<n;i++)
               {
                  scanf("%lf",&r);
                  v[i]=r*r*pi;
                  V+=v[i];
               }
               double l=0,R=V,mid;
               while(fabs(R-l)>EPS)
               {
                    mid=(l+R)/2;
                   if(judge(mid)>=f)  {l=mid;}
                   else              {R=mid;}
               }
               printf("%.4lf\n",mid);
          }
     return 0;
}

G-Flyer

http://acm.hdu.edu.cn/showproblem.php?pid=4768

Problem Description
The new semester begins! Different kinds of student societies are all trying to advertise themselves, by giving flyers to the students for introducing the society. However, due to the fund shortage, the flyers of a society can only be distributed to a part of the students. There are too many, too many students in our university, labeled from 1 to 2^32. And there are totally N student societies, where the i-th society will deliver flyers to the students with label A_i, A_i+C_i,A_i+2*C_i,…A_i+k*C_i (A_i+k*C_i<=B_i, A_i+(k+1)*C_i>B_i). We call a student "unlucky" if he/she gets odd pieces of flyers. Unfortunately, not everyone is lucky. Yet, no worries; there is at most one student who is unlucky. Could you help us find out who the unfortunate dude (if any) is? So that we can comfort him by treating him to a big meal!
 

Input
There are multiple test cases. For each test case, the first line contains a number N (0 < N <= 20000) indicating the number of societies. Then for each of the following N lines, there are three non-negative integers A_i, B_i, C_i (smaller than 2^31, A_i <= B_i) as stated above. Your program should proceed to the end of the file.
 

Output
For each test case, if there is no unlucky student, print "DC Qiang is unhappy." (excluding the quotation mark), in a single line. Otherwise print two integers, i.e., the label of the unlucky student and the number of flyers he/she gets, in a single line.
 

Sample Input
  
  
2 1 10 1 2 10 1 4 5 20 7 6 14 3 5 9 1 7 21 12
 

Sample Output
  
  
1 1 8 1

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long ll;
const int L=20005;
ll a[L],b[L],c[L];
int main()
{
     int i,j,n;
     while(~scanf("%d",&n))
     {
          for(i=0;i<n;i++)
          scanf("%lld%lld%lld",&a[i],&b[i],&c[i]);
          ll ans=0,cnt=0;
          for(i=0;i<n;i++)
              for(j=a[i];j<=b[i];j+=c[i])
                  ans^=j;
          if(ans)
          {
             for(i=0;i<n;i++)
                 for(j=a[i];j<=b[i];j+=c[i])
                    if(ans==j)cnt++;
              printf("%lld %lld\n",ans,cnt);
          }
          else
          printf("DC Qiang is unhappy.\n");
     }
      return 0;
}
#include<stdio.h>
#include<algorithm>
using namespace std;
#define ll __int64
#define N 20050

ll a[N],b[N],c[N],l,r,n;

int solve(ll mid)
{
     ll k,sum=0;
     int i;
     for(i=0;i<n;i++)
     {
         k=min(mid,b[i]);
         if(k>=a[i])
            sum+=(k-a[i])/c[i]+1;
     }
     return sum;
}
int main()
{
      int i,j;
      while(~scanf("%d",&n))
      {
          for(i=0;i<n;i++)
          {
              scanf("%d%d%d",&a[i],&b[i],&c[i]);
          }
          l=0,r=1ll<<31;
          ll mid;
          while(l<r)
          {
              mid=(l+r)>>1;
              if(solve(mid)%2)
                 r=mid;
              else
                 l=mid+1;
          }
          if(l==1ll<<31)
          {
              printf("DC Qiang is unhappy.\n");
          }
          else
          {
               while(!solve(l)%2)
                    l--;
                printf("%d %d\n",l,solve(l)-solve(l-1));
          }
      }
      return 0;
}


H-pog loves szh II  -二分((A+B )%mod)

Problem Description
Pog and Szh are playing games.There is a sequence with n numbers, Pog will choose a number A from the sequence. Szh will choose an another number named B from the rest in the sequence. Then the score will be (A+B) mod p.They hope to get the largest score.And what is the largest score?

Input
Several groups of data (no more than 5 groups,n≥1000).

For each case: 

The following line contains two integers,n(2≤n≤100000),p(1≤p≤231−1)。

The following line contains n integers ai(0≤ai≤231−1)。
 
Output
For each case,output an integer means the largest score.
 
Sample Input
4 4
1 2 3 0
4 4
0 0 2 2
 
Sample Output
3
2


#include<stdio.h>
#include<algorithm>
using namespace std;
typedef long long ll;
int main()
{
       ll n,m,p,x,a[100050];
       while(~scanf("%lld%lld",&n,&p))
       {
             for(int i=0;i<n;i++)
             {
                  scanf("%lld",&x);
                  a[i]=x%p;
             }
             sort(a,a+n);
             ll ans1=(a[n-1]+a[n-2])%p;
             ll ans2=0;
             ll l=0,r=n-1;
             while(l<r)
             {
                  ans2=max((a[l]+a[r])%p,ans2);
                  if(a[l]+a[r]>p)
                     r--;
                  else
                     l++;
             }
             printf("%lld\n",max(ans2,ans1));

       }return 0;
}

I-Rightmost Digit(快速幂)
http://acm.hdu.edu.cn/showproblem.php?pid=1061


  
  
Problem Description
Given a positive integer N, you should output the most right digit of N^N.
 

Input
The input contains several test cases. The first line of the input is a single integer T which is the number of test cases. T test cases follow. Each test case contains a single positive integer N(1<=N<=1,000,000,000).
 

Output
For each test case, you should output the rightmost digit of N^N.
 

Sample Input
    
    
2 3 4

 

Sample Output
     
     
7 6
Hint
In the first case, 3 * 3 * 3 = 27, so the rightmost digit is 7. In the second case, 4 * 4 * 4 * 4 = 256, so the rightmost digit is 6.


#include<stdio.h>
typedef long long ll;
const int mod=10;
ll qpow(ll a,ll b)
{
   ll ans=1;
   while(b)
   {
       if(b&1)
           ans=(ans*a)%mod;
       a=(a*a)%mod;
       b>>=1;
   }
   return ans;
}
int main()
{
     int T;
     scanf("%d",&T);
     while(T--)
     {
         ll n;
         scanf("%lld",&n);
         printf("%lld\n",qpow(n,n));
     }
     return 0;
}



J-zhx's contest
http://acm.hdu.edu.cn/showproblem.php?pid=5187

      
      
Problem Description
As one of the most powerful brushes, zhx is required to give his juniors  n  problems. zhx thinks the  ith  problem's difficulty is  i . He wants to arrange these problems in a beautiful way. zhx defines a sequence  {ai}  beautiful if there is an  i  that matches two rules below: 1:  a1..ai  are monotone decreasing or monotone increasing. 2:  ai..an  are monotone decreasing or monotone increasing. He wants you to tell him that how many permutations of problems are there if the sequence of the problems' difficulty is beautiful. zhx knows that the answer may be very huge, and you only need to tell him the answer module  p .
 

Input
Multiply test cases(less than  1000 ). Seek  EOF  as the end of the file. For each case, there are two integers  n  and  p  separated by a space in a line. ( 1n,p1018 )
 

Output
For each test case, output a single line indicating the answer.
 

Sample Input
        
        
2 233 3 5
 

Sample Output
         
         
2 1
Hint
In the first case, both sequence {1, 2} and {2, 1} are legal. In the second case, sequence {1, 2, 3}, {1, 3, 2}, {2, 1, 3}, {2, 3, 1}, {3, 1, 2}, {3, 2, 1} are legal, so the answer is 6 mod 5 = 1


#include<stdio.h>
#include<math.h>
#include<algorithm>
typedef long long ll;
using namespace std;
ll sucheng(ll a,ll b,ll mod)
{
     ll ans=0;
     while(b)
     {
         if(b&1)
         {
          ans=(ans+a);
          if(ans>=mod)ans-=mod;
         }
         a=a+a;
         if(a>=mod)
             a-=mod;
         b/=2;
     }
     return ans;
}
ll qpow(ll a,ll b,ll mod)
{
    a%=mod;
    ll ans=1;
    while(b)
    {
        if(b&1)
           ans=sucheng(ans,a,mod);
        a=sucheng(a,a,mod);
        b/=2;

    }
    return ans;
}
int main()
{
     ll mod,n;
     while(scanf("%lld%lld",&n,&mod)!=EOF)
     {
        printf("%lld\n",(qpow(2,n,mod)-2+mod)%mod);

     }
     return 0;
}


K-Binary Numbers


          
          
Problem Description
Given a positive integer n, find the positions of all 1's in its binary representation. The position of the least significant bit is 0. Example The positions of 1's in the binary representation of 13 are 0, 2, 3. Task Write a program which for each data set: reads a positive integer n, computes the positions of 1's in the binary representation of n, writes the result.
 

Input
The first line of the input contains exactly one positive integer d equal to the number of data sets, 1 <= d <= 10. The data sets follow. Each data set consists of exactly one line containing exactly one integer n, 1 <= n <= 10^6.
 

Output
The output should consists of exactly d lines, one line for each data set. Line i, 1 <= i <= d, should contain increasing sequence of integers separated by single spaces - the positions of 1's in the binary representation of the i-th input number.
 

Sample Input
            
            
1 13
 

Sample Output
             
             
0 2 3
#include<stdio.h>
int main()
{

      int i,n,T;
      while(~scanf("%d",&T))
      {
           while(T--)
           {
                int a[100000]={0};
                scanf("%d",&n);
                for(i=0;n;n/=2,i++)
                {
                     if(n&1)
                     a[i]++;
                }
                for(int j=0;j<i;j++)
                {
                      if(j[a])
                     printf(j==i-1?"%d\n":"%d ",j);
                }
           }
      }
      return 0;
}

L-符号三角形

http://acm.hdu.edu.cn/showproblem.php?pid=2510

             
             
Problem Description
符号三角形的 第1行有n个由“+”和”-“组成的符号 ,以后每行符号比上行少1个,2个同号下面是”+“,2个异 号下面是”-“ 。计算有多少个不同的符号三角形,使其所含”+“ 和”-“ 的个数相同 。 n=7时的1个符号三角形如下: + + - + - + +  + - - - - +  - + + + -  - + + -  - + -  - -  +
 

Input
每行1个正整数n <=24,n=0退出.
 

Output
n和符号三角形的个数. 
 

Sample Input
               
               
15 16 19 20 0
 

Sample Output
                
                
15 1896 16 5160 19 32757 20 59984
#include<stdio.h>
#include<string.h>
int dp[25][25],ans[25],cnt;
void dfs(int n)
{
      int i,j;
     if(n>24)
        return ;
     for(i=0;i<=1;i++)
     {
         dp[1][n]=i;
         cnt+=dp[1][n];
         for(j=2;j<=n;j++)
         {
             dp[j][n-j+1]=dp[j-1][n-j+1]^dp[j-1][n-j+2];
             cnt+=dp[j][n-j+1];
         }
         if(cnt*2==n*(n+1)/2)
         {
             ans[n]++;
         }
         dfs(n+1);
         cnt-=dp[1][n];
         for(j=2;j<=n;j++)
         {
             cnt-=dp[j][n-j+1];
         }
     }
}
int main()
{
     int n;
     dfs(1);
     while(scanf("%d",&n),n)
     {
           printf("%d\n",ans[n]);
     }
     return 0;
}

M-Connect the Cities

http://acm.hdu.edu.cn/showproblem.php?pid=3371

                
                
Problem Description
In 2100, since the sea level rise, most of the cities disappear. Though some survived cities are still connected with others, but most of them become disconnected. The government wants to build some roads to connect all of these cities again, but they don’t want to take too much money.  
 

Input
The first line contains the number of test cases. Each test case starts with three integers: n, m and k. n (3 <= n <=500) stands for the number of survived cities, m (0 <= m <= 25000) stands for the number of roads you can choose to connect the cities and k (0 <= k <= 100) stands for the number of still connected cities. To make it easy, the cities are signed from 1 to n. Then follow m lines, each contains three integers p, q and c (0 <= c <= 1000), means it takes c to connect p and q. Then follow k lines, each line starts with an integer t (2 <= t <= n) stands for the number of this connected cities. Then t integers follow stands for the id of these cities.
 

Output
For each case, output the least money you need to take, if it’s impossible, just output -1.
 

Sample Input
                  
                  
1 6 4 3 1 4 2 2 6 1 2 3 5 3 4 33 2 1 2 2 1 3 3 4 5 6
 

Sample Output
                   
                   
1
#include<stdio.h>
#include<string.h>
#define INF 0x3f3f3f3f
int vis[502],map[502][502],dis[502],n,su[502];
void prim()
{
	int point=1,length=0,i,j,min;
	memset(vis,0,sizeof(vis));
	for(i=1;i<=n;i++)
	   dis[i]=map[1][i];
	vis[1]=1;
   for(i=1;i<n;i++)
   {
     min=INF;
     for(j=1;j<=n;j++)
         if(!vis[j]&&dis[j]<min)
         {
           min=dis[j];
           point=j;
         }
         vis[point]=1;
		length+=min;
		if(length>=INF) break;
		for(j=1;j<=n;j++)
		   if(!vis[j]&&dis[j]>map[point][j])
		      dis[j]=map[point][j];
    }
    if(length>=INF) printf("-1\n");
    else printf("%d\n",length);
}
int main()
{
	int T,m,k,a,b,c,t,i,j;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d%d%d",&n,&m,&k);
		memset(map,INF,sizeof(map));
		while(m--)
		{
			scanf("%d%d%d",&a,&b,&c);
			if(map[a][b]>c) map[a][b]=map[b][a]=c;
		}
		while(k--)
		{
			scanf("%d",&t);
			for(i=1;i<=t;i++)
			{
				scanf("%d",&su[i]);
		        for(j=1;j<i;j++)
		          map[su[i]][su[j]]=map[su[j]][su[i]]=0;
			}
		}
		prim();
	}
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值