三家人
Time Limit: 1 Sec
Memory Limit: 128 MB
Submit: 2170
Solved: 838
[ Submit][ Status][ Web Board]
Description
有三户人家共拥有一座花园,每户人家的太太均需帮忙整理花园。A 太太工作了5 天,B 太太则工作了4 天,才将花园整理完毕。C 太太因为正身怀六甲无法加入她们的行列,便出了90元。请问这笔钱如何分给A、B 二位太太较为恰当?A 应得多少元?90/(5+4)*5=$50 元?如果这么想你就上当了!正确答案是60 元。如果没想通的话再想想吧。
下面回答一个一般性的问题:假定A 太太工作了x 天,B 太太工作了y 天,C 太太出了90元,则A 太太应得多少元?输入保证二位太太均应得到非负整数元钱。三个太太工作效率相同。
友情提示:本题有个小小的陷阱哦。如果答案错的话,认真检查一下代码吧。
Input
输入第一行为数据组数T (T<=20)。每组数据仅一行,包含三个整数x, y, z (1<=x, y<=10,1<=z<=1000)。
Output
对于每组数据,输出一个整数,即A 太太应得的金额(单位:元)。
Sample Input
2
5 4 90
8 4 123
Sample Output
60
123
HINT
如果使用浮点数,请小心误差,输出时尽量用四舍五入。
思路:题目已经提示你了不能直接按照AB的比例去求结果。正确的求法应该是先求出三个人一起需要做多少天,然后算出A和B分别帮C做了多少天,最后求比例即可。
代码:
#include
#include
#include
#include
#include
#include
机器人的指令
Time Limit: 1 Sec
Memory Limit: 128 MB
Submit: 1790
Solved: 651
[ Submit][ Status][ Web Board]
Description
数轴原点有一个机器人。该机器人将执行一系列指令,你的任务是预测所有指令执行完毕之后它的位置。
·LEFT:往左移动一个单位
·RIGHT: 往右移动一个单位
·SAME AS i: 和第i 条执行相同的动作。输入保证i 是一个正整数,且不超过之前执行指令数
Input
输入第一行为数据组数T (T<=100)。每组数据第一行为整数n (1<=n<=100),即指令条数。以下每行一条指令。指令按照输入顺序编号为1~n。
Output
对于每组数据,输出机器人的最终位置。每处理完一组数据,机器人应复位到数轴原点。
Sample Input
2
3
LEFT
RIGHT
SAME AS 2
5
LEFT
SAME AS 1
SAME AS 2
SAME AS 1
SAME AS 4
Sample Output
1
-5
思路:用一个数组记录每一次做了哪个操作,-1表示向左,1表示向右即可
代码:
#include
#include
#include
#include
#include
#include
Updating a Dictionary
Time Limit: 1 Sec
Memory Limit: 128 MB
Submit: 745
Solved: 180
[ Submit][ Status][ Web Board]
Description
In this problem, a dictionary is collection of key-value pairs, where keys are lower-case letters, and values are non-negative integers. Given an old dictionary and a new dictionary, find out what were changed.
Each dictionary is formatting as follows:
{key:value,key:value,...,key:value}
Each key is a string of lower-case letters, and each value is a non-negative integer without leading zeros or prefix '+'. (i.e. -4, 03 and +77 are illegal). Each key will appear at most once, but keys can appear in any order.
Input
The first line contains the number of test cases T (T<=1000). Each test case contains two lines. The first line contains the old dictionary, and the second line contains the new dictionary. Each line will contain at most 100 characters and will not contain any whitespace characters. Both dictionaries could be empty.
WARNING:
there are no restrictions on the lengths of each key and value in the dictionary. That means keys could be really long and values could be really large.
Output
For each test case, print the changes, formatted as follows:
·First, if there are any new keys, print '+' and then the new keys in increasing order (lexicographically), separated by commas.
·Second, if there are any removed keys, print '-' and then the removed keys in increasing order (lexicographically), separated by commas.
·Last, if there are any keys with changed value, print '*' and then these keys in increasing order (lexicographically), separated by commas.
If the two dictionaries are identical, print 'No changes' (without quotes) instead.
Print a blank line after each test case.
Sample Input
3
{a:3,b:4,c:10,f:6}
{a:3,c:5,d:10,ee:4}
{x:1,xyz:123456789123456789123456789}
{xyz:123456789123456789123456789,x:1}
{first:1,second:2,third:3}
{third:3,second:2}
Sample Output
+d,ee
-b,f
*c
No changes
-first
思路:用两个map去存下两个字符串里边的信息,然后作比较即可
代码:
#include
#include
#include
#include
#include
平方根大搜索
Time Limit: 5 Sec
Memory Limit: 128 MB
Submit: 184
Solved: 98
[ Submit][ Status][ Web Board]
Description
在二进制中,2的算术平方根,即sqrt(2),是一个无限小数1.0110101000001001111...
给定一个整数n和一个01串S,你的任务是在sqrt(n)的小数部分(即小数点之后的部分)中找到S第一次出现的位置。如果sqrt(n)是整数,小数部分看作是无限多个0组成的序列。
Input
输入第一行为数据组数T (T<=20)。以下每行为一组数据,仅包含一个整数n (2<=n<=1,000,000)和一个长度不超过20的非空01串S。
Output
对于每组数据,输出S的第一次出现中,第一个字符的位置。小数点后的第一个数字的位置为0。输入保证答案不超过100。
Sample Input
2
2 101
1202 110011
Sample Output
2
58
思路:此题可以用手动模拟开方做,不过实在太麻烦了,并且如果事先不知道模拟的过程是做不出来的。
所以这里我们用二分去找开方即可,然后手动转换为二进制,最后暴力比较。
代码:
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.text.Format;
import java.util.Scanner;
public class Main {
final static BigDecimal eps = BigDecimal.valueOf(0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001);
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int tcase = sc.nextInt();
while(tcase-- > 0){
String str = sc.next();
String str1 = sc.next();
BigDecimal a = new BigDecimal(str);
a.setScale(200);
BigDecimal l = BigDecimal.ZERO;
l.setScale(200);
BigDecimal r = a;
r.setScale(200);
BigDecimal mid = new BigDecimal("0");
mid.setScale(200);
while(l.add(eps).compareTo(r)<=0){
mid = l.add(r).divide(BigDecimal.valueOf(2));
if(mid.multiply(mid).compareTo(a)>0){
r = mid;
}else{
l = mid;
}
}
String s = mid.toString();
int idx = 0;
for(int i=0;i=0){
ans+=1;
mid = mid.subtract(BigDecimal.ONE);
}else{
ans+=0;
}
}
int res = ans.indexOf(str1);
System.out.println(res);
}
}
}
最短的名字
Time Limit: 5 Sec
Memory Limit: 64 MB
Submit: 1126
Solved: 422
[ Submit][ Status][ Web Board]
Description
在一个奇怪的村子中,很多人的名字都很长,比如aaaaa, bbb and abababab。
名字这么长,叫全名显然起来很不方便。所以村民之间一般只叫名字的前缀。比如叫'aaaaa'的时候可以只叫'aaa',因为没有第二个人名字的前三个字母是'aaa'。不过你不能叫'a',因为有两个人的名字都以'a'开头。村里的人都很聪明,他们总是用最短的称呼叫人。输入保证村里不会有一个人的名字是另外一个人名字的前缀(作为推论,任意两个人的名字都不会相同)。
如果村里的某个人要叫所有人的名字(包括他自己),他一共会说多少个字母?
Input
输入第一行为数据组数T (T<=10)。每组数据第一行为一个整数n(1<=n<=1000),即村里的人数。以下n行每行为一个人的名字(仅有小写字母组成)。输入保证一个村里所有人名字的长度之和不超过1,000,000。
Output
Sample Input
1
3
aaaaa
bbb
abababab
Sample Output
5
思路:用字典树存下所有的串,在子点数上记录每一个位置被经过了多少次。然后从根结点开始扫,每次扫到1就ans+=len,然后return即可
代码:
#include
#include
#include
#include
#include
#include
Kingdoms
Time Limit: 3 Sec
Memory Limit: 64 MB
Submit: 427
Solved: 137
[ Submit][ Status][ Web Board]
Description
A kingdom has n cities numbered 1 to n, and some bidirectional roads connecting cities. The capital is always city 1.
After a war, all the roads of the kingdom are destroyed. The king wants to rebuild some of the roads to connect the cities, but unfortunately, the kingdom is running out of money. The total cost of rebuilding roads should not exceed K.
Given the list of m roads that can be rebuilt (other roads are severely damaged and cannot be rebuilt), the king decided to maximize the total population in the capital and all other cities that are connected (directly or indirectly) with the capital (we call it "accessible population"), can you help him?
Input
The first line of input contains a single integer T (T<=20), the number of test cases.
Each test case begins with three integers n(4<=n<=16), m(1<=m<=100) and K(1<=K<=100,000).
The second line contains n positive integers pi (1<=pi<=10,000), the population of each city.
Each of the following m lines contains three positive integers u, v, c (1<=u,v<=n, 1<=c<=1000), representing a destroyed road connecting city u and v, whose rebuilding cost is c.
Note that two cities can be directly connected by more than one road, but a road cannot directly connect a city and itself.
Output
For each test case, print the maximal accessible population.
Sample Input
2
4 6 6
500 400 300 200
1 2 4
1 3 3
1 4 2
4 3 5
2 4 6
3 2 7
4 6 5
500 400 300 200
1 2 4
1 3 3
1 4 2
4 3 5
2 4 6
3 2 7
Sample Output
1100
1000
题意:有n个城市和m条路,k块钱,每个城市有一个权值。国王居住在1号城市,现在问你如何选出一些边总费用不超过k,使得跟1号城市连接的所有城市权值最大
思路:数据量比较小,城市只有16个,所有我们可以用状态保存下16个城市所有的状态,1表示已经选入,0表示未选入。
这样状态总数也只有1<<16=65536 所以我们可以枚举所有的状态,然后用prim求出连通这些为1的结点所需要的最小费用是否大于k,枚举完后在费用<=k的状态里面取权值最大的即可。 注意1号城市一定会选入,这样状态可以少一维。
代码:
#include
#include
#include
#include
#include
Collecting Coins
Time Limit: 3 Sec
Memory Limit: 128 MB
Submit: 315
Solved: 68
[ Submit][ Status][ Web Board]
Description
In a maze of r rows and c columns, your task is to collect as many coins as possible.
Each square is either your start point "S"(which will become empty after you leave), an empty square ".", a coin square "C" (which will become empty after you step on this square and thus collecting the coin), a rock square "O" or an obstacle square "X".
At each step, you can move one square to the up, down, left or right. You cannot leave the maze or enter an obstacle square, but you can push each rock at most once (i.e. You can treat a rock as an obstacle square after you push it).
To push a rock, you must stand next to it. You can only push the rock along the direction you're facing, into an neighboring empty square (you can't push it outside the maze, and you can't push it to a squarecontiaining a coin).For example, if the rock is to your immediate right, you can only push it to its right neighboring square.
Find the maximal number of coins you can collect.
Input
The first line of input contains a single integer T (T<=25), the number of test cases.
Each test case begins with two integers r and c (2<=r,c<=10), then followed by r lines, each with c columns.
There will be at most 5 rocks and at most 10 coins in each maze.
Output
For each test case, print the maximal number of coins you can collect.
Sample Input
3
3 4
S.OC
..O.
.XCX
4 6
S.X.CC
..XOCC
...O.C
....XC
4 4
.SXC
OO.C
..XX
.CCC
Sample Output
1
6
3
题意:有一个n*m的矩阵,S是人开始的位置,O是石头,C是金币,X是墙。石头最多只能推一次,现在问你最多能拿到多少个金币
思路:我们不能直接用人去做BFS一条路走到死。肯定会TLE,因为在碰到石头之前的状态其实都是一样的,而你用BFS会多出很多很多状态。
所以我们先用BFS跑出石头没动时人能走到的所有的位置,并且把吃到的金币数记下来,对应的图从C改成.
然后用DFS去枚举石头移动的所有情况(向四个方向移动),最后在所有情况里面取吃到的金币数最大的那个就可以了。注意要开三维数组保存上一层的图和标记数组。
代码:
#include
#include
#include
#include
#include
#include
using namespace std;
int n,m,ans,last_ans;
char ma[6][11][11];
int dir[4][2]= {-1,0,1,0,0,-1,0,1};
struct Node
{
int x,y;
} stone[5];
int cnt;
int vis[6][15][15];
int flag[5],num;
bool check(Node a,int k)
{
if(a.x<0||a.x>=n||a.y<0||a.y>=m) return false;
if(ma[k][a.x][a.y]=='X'||ma[k][a.x][a.y]=='O') return false;
return true;
}
void bfs(Node a,int k)
{
Node now,next;
queueque;
que.push(a);
vis[k][a.x][a.y]=1;
while(!que.empty())
{
now=que.front();
que.pop();
for(int i=0; i<4; i++)
{
next.x=now.x+dir[i][0];
next.y=now.y+dir[i][1];
if(!check(next,k)||vis[k][next.x][next.y]) continue;
if(ma[k][next.x][next.y]=='C')
{
ans++;
last_ans=max(ans,last_ans);
ma[k][next.x][next.y]='.';
}
vis[k][next.x][next.y]=1;
que.push(next);
}
}
}
void dfs(int k)
{
for(int i=0; i=n||ty<0||ty>=m||ma[k-1][tx][ty]!='.') continue;
int ttx=stone[i].x-dir[j][0];
int tty=stone[i].y-dir[j][1];
if(ttx<0||ttx>=n||tty<0||tty>=m||!vis[k-1][ttx][tty]) continue;
memcpy(vis[k],vis[k-1],sizeof(vis[k]));
memcpy(ma[k],ma[k-1],sizeof(ma[k]));
ma[k][tx][ty]='X',ma[k][stone[i].x][stone[i].y]='.';
flag[i]=1;
bfs(stone[i],k);
if(last_ans==num) return;
dfs(k+1);
if(last_ans==num) return;
for(int i=0; i
病毒
Time Limit: 3 Sec
Memory Limit: 128 MB
Submit: 930
Solved: 395
[ Submit][ Status][ Web Board]
Description
你有一个日志文件,里面记录着各种系统事件的详细信息。自然的,事件的时间戳按照严格递增顺序排列(不会有两个事件在完全相同的时刻发生)。
遗憾的是,你的系统被病毒感染了,日志文件中混入了病毒生成的随机伪事件(但真实事件的相对顺序保持不变)。备份的日志文件也被感染了,但由于病毒采用的随机感染方法,主日志文件和备份日志文件在感染后可能会变得不一样。
给出被感染的主日志和备份日志,求真实事件序列的最长可能长度。
Input
输入第一行为数据组数T (T<=100)。每组数据包含两行,分别描述感染后的主日志和备份日志。
每个日志文件的格式相同,均为一个整数n (1<=n<=1000)(代表感染后的事件总数)和n 个不超过100,000的正整数(表示感染后各事件的时间戳)。
注意,感染后可能会出现时间戳完全相同的事件。
Output
Sample Input
1
9 1 4 2 6 3 8 5 9 1
6 2 7 6 3 5 1
Sample Output
3
思路:裸的LCIS,做LCS的时候维护上升即可
代码:
#include
#include
#include
#include
#include
#include