HDOJ-ACM Steps

在这里放几道Steps里的题目把。

find your present (2)

Time Limit: 1000/2000 MS (Java/Others) Memory Limit: 32768/1024 K (Java/Others)
Total Submission(s): 4570 Accepted Submission(s): 1343

Problem Description
In the new year party, everybody will get a "special present".Now it's your turn to get your special present, a lot of presents now putting on the desk, and only one of them will be yours.Each present has a card number on it, and your present's card number will be the one that different from all the others, and you can assume that only one number appear odd times.For example, there are 5 present, and their card numbers are 1, 2, 3, 2, 1.so your present will be the one with the card number of 3, because 3 is the number that different from all the others.
 

Input
The input file will consist of several cases.
Each case will be presented by an integer n (1<=n<1000000, and n is odd) at first. Following that, n positive integers will be given in a line, all integers will smaller than 2^31. These numbers indicate the card numbers of the presents.n = 0 ends the input.
 

Output
For each case, output an integer in a line, which is the card number of your present.
 

Sample Input
5
1 1 3 2 2
3
1 2 1
0
 

Sample Output
3
2
Hint
Hint
use scanf to avoid Time Limit Exceeded

在使用桶排序、每输入一次往上遍历的方法后依然Runtime Error (STACK_OVERFLOW)

于是使用“异或”进行运算

解题思路:

 比如   3^5,   3=011,5=101,两数按位异或后为110,即6。
偶数次出现的异或结果为0 基数次结果为1
然后 异或满足交换率
再举一个例子。
如 数据 1 2 3 2 1
先让result=0
那么可以看成是 result^1^2^3^2^1
交换律 result^1^1^2^2^3
很明显 1^1 和 2^2 都为 0
所以最后得 result^3 =0^3 =3(二进制 101)
AC代码:
 1 #include <stdio.h>
 2 #include <string.h>
 3 int main()
 4 {
 5     int n,res,i,j;
 6     int x;
 7     while(scanf("%d",&n)!=EOF)
 8     {
 9         if(n==0)
10             break;
11         res=0;
12         for(i=0;i<n;i++)
13         {
14             scanf("%d",&x);
15             res=res^x;
16         }
17         printf("%d\n",res);
18     }
19     return 0;
20 }
View Code

 

 
 

排序

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 3499 Accepted Submission(s): 1008

Problem Description
输入一行数字,如果我们把这行数字中的‘5’都看成空格,那么就得到一行用空格分割的若干非负整数(可能有些整数以‘0’开头,这些头部的‘0’应该被忽略掉,除非这个整数就是由若干个‘0’组成的,这时这个整数就是0)。

你的任务是:对这些分割得到的整数,依从小到大的顺序排序输出。

 

Input
输入包含多组测试用例,每组输入数据只有一行数字(数字之间没有空格),这行数字的长度不大于1000。  

输入数据保证:分割得到的非负整数不会大于100000000;输入数据不可能全由‘5’组成。
 

Output
对于每个测试用例,输出分割得到的整数排序的结果,相邻的两个整数之间用一个空格分开,每组输出占一行。
 

Sample Input
0051231232050775
 

Sample Output
0 77 12312320
注意事项: 如果是005123123205077555555555
      输出也是 0 77 12312320
如果此处不特殊考虑容易WA
AC代码:
 1 #include <stdio.h>
 2 #include <string.h>
 3 int main()
 4 {
 5     int ti,k,i,j,len,tmp;
 6     int a[1001];
 7     char n[1001];
 8     while(gets(n))
 9     {
10         k=0;
11         ti=1;
12         tmp=0;
13         len=strlen(n);
14         for(i=len-1;i>=0;i--)
15         {
16           // printf("%d tmp:%d\n",n[i]-'0',tmp);
17             if(i==len-1&&n[i]=='5')
18                 continue;
19             else if(n[i]=='5')
20             {
21                 if(n[i+1]=='5')
22                     continue;
23                 a[k]=tmp;
24                 k++;
25                 ti=1;
26                 tmp=0;
27             }
28             else if(i==0&&n[i]!='5')
29             {
30                 tmp+=ti*(n[i]-'0');
31                 ti*=10;
32                 a[k]=tmp;
33                 k++;
34                 ti=1;
35                 tmp=0;
36             }
37             else
38             {
39                 tmp+=ti*(n[i]-'0');
40                 ti*=10;
41             }
42         }
43         for(i=1;i<k;i++)
44         {
45             for(j=k-1;j>=i;j--)
46             {
47                 if(a[j]<a[j-1])
48                 {
49                     tmp=a[j];a[j]=a[j-1];a[j-1]=tmp;
50                 }
51             }
52         }
53         for(i=0;i<k;i++)
54         {
55             if(i<k-1)
56                 printf("%d ",a[i]);
57             else
58                 printf("%d\n",a[i]);
59         }
60     }
61     return 0;
62 }
View Code
 
 

 

排名

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 3051 Accepted Submission(s): 991

Problem Description
今天的上机考试虽然有实时的Ranklist,但上面的排名只是根据完成的题数排序,没有考虑
每题的分值,所以并不是最后的排名。给定录取分数线,请你写程序找出最后通过分数线的
考生,并将他们的成绩按降序打印。
 

Input
测试输入包含若干场考试的信息。每场考试信息的第1行给出考生人数N ( 0 < N
< 1000 )、考题数M ( 0 < M < = 10 )、分数线(正整数)G;第2行排序给出第1题至第M题的正整数分值;以下N行,每行给出一
名考生的准考证号(长度不超过20的字符串)、该生解决的题目总数m、以及这m道题的题号
(题目号由1到M)。
当读入的考生人数为0时,输入结束,该场考试不予处理。
 

Output
对每场考试,首先在第1行输出不低于分数线的考生人数n,随后n行按分数从高
到低输出上线考生的考号与分数,其间用1空格分隔。若有多名考生分数相同,则按他们考
号的升序输出。
 

Sample Input
4 5 25
10 10 12 13 15
CS004 3 5 1 3
CS003 5 2 4 1 3 5
CS002 2 1 2
CS001 3 2 3 5
1 2 40
10 30
CS001 1 2
2 3 20
10 10 10
CS000000000000000001 0
CS000000000000000002 2 1 2
0
 

Sample Output
3
CS003 60
CS001 37
CS004 37
0
1
CS000000000000000002 20
Hint
 写这题,QAQ,第一次同时两个对象进行排序
AC代码:
 1 #include <stdio.h>
 2 #include <string.h>
 3 struct stu
 4 {
 5     char n[21];
 6     int sum;
 7     int a[11];
 8     int score;
 9     int flag;
10 }a[1001],tmp;
11 int main()
12 {
13     int n,m,g,i,j,w,x,k;
14     int b[11];
15     while(scanf("%d",&n)!=EOF)
16     {
17         k=0;
18         if(n==0)
19             break;
20         scanf("%d %d",&m,&g);
21         for(i=0;i<m;i++)
22             scanf("%d",&b[i]);
23         for(i=0;i<n;i++)
24         {
25             scanf("%s %d",a[i].n,&a[i].sum);
26             a[i].score=0;
27             for(j=0;j<a[i].sum;j++)
28             {
29                 scanf("%d",&a[i].a[j]);
30                 a[i].score+=b[a[i].a[j]-1];
31             }
32             if(a[i].score>=g)
33                 k++;
34         }
35         for(i=1;i<n;i++)
36         {
37             for(j=n-1;j>=i;j--)
38             {
39                 if(a[j].score>a[j-1].score)
40                 {
41                     tmp=a[j];a[j]=a[j-1];a[j-1]=tmp;
42                 }
43                 else if(a[j].score==a[j-1].score)
44                 {
45                     if(strcmp(a[j].n,a[j-1].n)<0)
46                     {
47                         tmp=a[j];a[j]=a[j-1];a[j-1]=tmp;
48                     }
49                 }
50             }
51         }
52         printf("%d\n",k);
53         for(i=0;i<k;i++)
54             printf("%s %d\n",a[i].n,a[i].score);
55     }
56     return 0;
57 }
View Code
 
 

 

Wooden Sticks

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1981 Accepted Submission(s): 779

Problem Description
There is a pile of n wooden sticks. The length and weight of each stick are known in advance. The sticks are to be processed by a woodworking machine in one by one fashion. It needs some time, called setup time, for the machine to prepare processing a stick. The setup times are associated with cleaning operations and changing tools and shapes in the machine. The setup times of the woodworking machine are given as follows:

(a) The setup time for the first wooden stick is 1 minute.
(b) Right after processing a stick of length l and weight w , the machine will need no setup time for a stick of length l' and weight w' if l<=l' and w<=w'. Otherwise, it will need 1 minute for setup.

You are to find the minimum setup time to process a given pile of n wooden sticks. For example, if you have five sticks whose pairs of length and weight are (4,9), (5,2), (2,1), (3,5), and (1,4), then the minimum setup time should be 2 minutes since there is a sequence of pairs (1,4), (3,5), (4,9), (2,1), (5,2).
 

Input
The input consists of T test cases. The number of test cases (T) is given in the first line of the input file. Each test case consists of two lines: The first line has an integer n , 1<=n<=5000, that represents the number of wooden sticks in the test case, and the second line contains n 2 positive integers l1, w1, l2, w2, ..., ln, wn, each of magnitude at most 10000 , where li and wi are the length and weight of the i th wooden stick, respectively. The 2n integers are delimited by one or more spaces.
 

Output
The output should contain the minimum setup time in minutes, one per line.
 

Sample Input
3 
5 
4 9 5 2 2 1 3 5 1 4 
3 
2 2 1 1 2 2 
3 
1 3 2 2 3 1
 

Sample Output
2
1
3
 这是我AC的第一道贪心题,一开始差不多写出来的时候自己测试却发现有问题,一直想不到。
后来才发现原来是是忘记对FLAG数组初始化导致后面的判断会直接跳过T^T
好吧,直接上AC代码:
 
 1 // 贪心算法---先排序---后选择第一个没有用过的木头一次向后找,用掉所有可以用掉的木头,然后返回第一个没用过的木头继续找
 2 #include <stdio.h>
 3 #include <string.h>
 4 struct sticks
 5 {
 6     int a;
 7     int b;
 8 }a[5001],tmp;
 9 int main()
10 {
11     int i,j,t,n,st,count;
12     int flag[5001],ti;
13     while(scanf("%d",&t)!=EOF)
14     {
15         while(t--)
16         {
17             for(i=0;i<5001;i++)
18                 flag[i]=0;//对flag数组清零
19             scanf("%d",&n);
20             for(i=0;i<n;i++)
21                 scanf("%d%d",&a[i].a,&a[i].b);
22             for(i=1;i<n;i++)//按照长度从小到大排序,若长度相同按照重量递增排序
23             {
24                 for(j=n-1;j>=i;j--)
25                 {
26                     if(a[j].a<a[j-1].a || a[j].a==a[j-1].a && a[j].b<a[j-1].b)
27                     {
28                         tmp=a[j];a[j]=a[j-1];a[j-1]=tmp;
29                     }
30                 }
31             }
32             st=0; //记录第一个没有用过的木头,st为其下标
33             count=0;
34             flag[0]=1;//从a[0]开始,故对a[0]元素作使用标记
35             while(st<n)
36             {
37                 ++count;//一次安装耗时
38                 for(i=st+1,j=st,ti=1;i<n;++i)//j为当前操作木棒下标,i为下一待操作木棒下标,ti为有无尚未使用木棒的标识符号
39                 {
40                     if(flag[i])//检查下标为i的目标是否已被使用
41                         continue;
42                     if(a[j].a<=a[i].a&&a[j].b<=a[i].b)
43                     {
44                         flag[i]=1;//赋予使用过木棒flag标示符为1
45                         j=i;//当前木棒下标即为i
46                     }
47                     else
48                     {
49                         if(ti)//如果ti!=0
50                         {
51                             st=i;//只记录第一个没用过的木头
52                             ti=0;//表明有尚未使用过的木棒
53                         }
54                     }
55                 }
56                 if(ti)//遍历完所有木棒,但仍找不到没使用过的木棒,ti==1,说明都用过了,跳出循环
57                     break;
58             }
59             printf("%d\n",count);
60         }
61     }
62     return 0;
63 }
View Code

Crixalis's Equipment

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2426 Accepted Submission(s): 721

Problem Description
Crixalis - Sand King used to be a giant scorpion(蝎子) in the deserts of Kalimdor. Though he's a guardian of Lich King now, he keeps the living habit of a scorpion like living underground and digging holes.

Someday Crixalis decides to move to another nice place and build a new house for himself (Actually it's just a new hole). As he collected a lot of equipment, he needs to dig a hole beside his new house to store them. This hole has a volume of V units, and Crixalis has N equipment, each of them needs Ai units of space. When dragging his equipment into the hole, Crixalis finds that he needs more space to ensure everything is placed well. Actually, the ith equipment needs Bi units of space during the moving. More precisely Crixalis can not move equipment into the hole unless there are Bi units of space left. After it moved in, the volume of the hole will decrease by Ai. Crixalis wonders if he can move all his equipment into the new hole and he turns to you for help.
 

Input
The first line contains an integer T, indicating the number of test cases. Then follows T cases, each one contains N + 1 lines. The first line contains 2 integers: V, volume of a hole and N, number of equipment respectively. The next N lines contain N pairs of integers: Ai and Bi.
0<T<= 10, 0<V<10000, 0<N<1000, 0 <Ai< V, Ai <= Bi < 1000.
 

Output
For each case output "Yes" if Crixalis can move all his equipment into the new hole or else output "No".
 

Sample Input
2

20 3
10 20
3 10
1 7

10 2
1 10
2 11
 

Sample Output
Yes
No

写这题的时候丝毫没感觉这提是贪心题,但是WA了几次还是没有AC的情况下

反过来想,要把n件物品全部搬到洞里,需要的最小空间是多少?

那么就很明显看出来这是一道贪心题

解题思路:

假设有物品 10  20 (thing 1)

       1   7 (thing 2)

先搬物品1后搬物品2需要的最小空间是:max(20,10+7)=20

先搬物品2后搬物品1需要的最小空间是:max(7,1+20)=21

那么我们选择的会是 先搬物品1后搬物品2

物品1和物品2的差别在于(BI-AI)的值

故因此的出:

贪心策略是 先搬差值大的,相等就随意!!

AC代码:

 1 #include <stdio.h>
 2 #include <string.h>
 3 struct sc
 4 {
 5     int a,b,c;
 6 }a[1001],tmp;
 7 int main()
 8 {
 9     int t,i,j,v,n;
10     while(scanf("%d",&t)!=EOF)
11     {
12         while(t--)
13         {
14             scanf("%d%d",&v,&n);
15             for(i=0;i<n;i++)
16             {
17                 scanf("%d%d",&a[i].a,&a[i].b);
18                 a[i].c=a[i].b-a[i].a;
19             }
20             for(i=1;i<n;i++)
21             {
22                 for(j=n-1;j>=i;j--)
23                 {
24                     if(a[j].c>a[j-1].c)
25                     {
26                         tmp=a[j];a[j]=a[j-1];a[j-1]=tmp;
27                     }
28                 }
29             }
30             for(i=0;i<n;i++)
31             {
32                 if(a[i].b>v)
33                 {
34                     printf("No\n");
35                     break;
36                 }
37                 v-=a[i].a;
38                 if(i==n-1)
39                     printf("Yes\n");
40             }
41         }
42     }
43     return 0;
44 }
View Code

 

Leftmost Digit

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 2142 Accepted Submission(s): 939
 
Problem Description
Given a positive integer N, you should output the leftmost 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 leftmost digit of N^N.
 
Sample Input
2
3
4
 
Sample Output
2
2
Hint
In the first case, 3 * 3 * 3 = 27, so the leftmost digit is 2. In the second case, 4 * 4 * 4 * 4 = 256, so the leftmost digit is 2.
对一个数num可写为 num=10 n + a, 即科学计数法,使a的整数部分即为num的最高位数字
 
num num =10 n + a 这里的n与上面的n不等
 
两边取对数: num*lg(num) = n + lg(a);
 
因为a<10,所以0<lg(a)<1
 
令x=n+lg(a); 则n为x的整数部分,lg(a)为x的小数部分
 
又x=num*lg(num);
a=10 (x-n) = 10 (x-int(x)))
 
再取a的整数部分即得num的最高位
AC代码:
 1 #include<stdio.h>
 2 #include<math.h>
 3 int main()
 4 {
 5     int t,a,n;
 6     double x;
 7     while(scanf("%d",&t)!=EOF)
 8     {
 9         while(t--)
10         {
11             scanf("%d",&n);
12             x=n*log10(n*1.00000);
13             x-=(__int64)x;
14             a=pow(10.0000,x);
15             printf("%d\n",a);
16         }
17     }
18     return 0;
19 }
View Code

 

转载于:https://www.cnblogs.com/wushuaiyi/p/3525400.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值