A 三家人
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
A太太和B太太工作的天数总除以三为每位太太应该工作的天数,减去这个数是帮助C太太工作的天数
#include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <vector> #include <queue> #include <cstdlib> #include <iomanip> #include <cmath> #include <ctime> #include <map> #include <set> using namespace std; #define lowbit(x) (x&(-x)) #define max(x,y) (x>y?x:y) #define min(x,y) (x<y?x:y) #define MAX 100000000000000000 #define MOD 1000000007 #define pi acos(-1.0) #define ei exp(1) #define PI 3.141592653589793238462 #define ios() ios::sync_with_stdio(false) #define INF 1044266558 #define mem(a) (memset(a,0,sizeof(a))) typedef long long ll; int t; double w,n,m; int main() { scanf("%d",&t); while(t--) { scanf("%lf%lf%lf",&n,&m,&w); double k=(m+n)/1.0; double a=n-(k/3.0); double b=m-(k/3.0); if(a<=0) printf("0 "); else if(b<=0) printf("%.lf ",w); else printf("%.lf ",w*a/(a+b)); } return 0; }
B 机器人的指令
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
水题
#include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <vector> #include <queue> #include <cstdlib> #include <iomanip> #include <cmath> #include <ctime> #include <map> #include <set> using namespace std; #define lowbit(x) (x&(-x)) #define max(x,y) (x>y?x:y) #define min(x,y) (x<y?x:y) #define MAX 100000000000000000 #define MOD 1000000007 #define pi acos(-1.0) #define ei exp(1) #define PI 3.141592653589793238462 #define ios() ios::sync_with_stdio(false) #define INF 1044266558 #define mem(a) (memset(a,0,sizeof(a))) typedef long long ll; int a[110],t,n,k; char ch[8],cch[5]; int main() { scanf("%d",&t); while(t--) { scanf("%d",&n); int pos=0; for(int i=1;i<=n;i++) { scanf("%s",ch); if(ch[0]=='L') a[i]=-1,pos+=a[i]; else if(ch[0]=='R') a[i]=1,pos+=a[i]; else scanf("%s%d",cch,&k),a[i]=a[k],pos+=a[i]; } printf("%d ",pos); } return 0; }
C:Updating a Dictionary
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
大模拟,注意输出规则,和键和值都为空时的判断情况
#include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <vector> #include <queue> #include <cstdlib> #include <iomanip> #include <cmath> #include <ctime> #include <map> #include <set> using namespace std; #define lowbit(x) (x&(-x)) #define max(x,y) (x>y?x:y) #define min(x,y) (x<y?x:y) #define MAX 100000000000000000 #define MOD 1000000007 #define pi acos(-1.0) #define ei exp(1) #define PI 3.141592653589793238462 #define ios() ios::sync_with_stdio(false) #define INF 1044266558 #define mem(a) (memset(a,0,sizeof(a))) typedef long long ll; char a[1000009]; set<string>s,sadd,smultiply; set<string>::iterator it; map<string,string>m; int t,ok,flag; int main() { scanf("%d",&t); while(t--) { scanf("%s",&a); int len=strlen(a); string sa,sb; int la=0,lb=0; flag=0; for(int i=1;i<len;i++) { if(a[i]==':') flag^=1; else if(a[i]==',' || a[i]=='}') { if(la || lb) m[sa]=sb,s.insert(sa),sa="",sb="",flag^=1; la=0;lb=0; } else if(flag) { if(a[i]!='+') sb+=a[i],lb++; } else sa+=a[i],la++; } scanf("%s",&a); len=strlen(a); flag=0; for(int i=1;i<len;i++) { if(a[i]==':') flag^=1; else if(a[i]==',' || a[i]=='}') { flag^=1; if(la || lb) { if(s.count(sa)==0) sadd.insert(sa); else { if(m[sa]!=sb) smultiply.insert(sa); s.erase(sa); } } sa="";sb="";la=0;lb=0; } else if(flag) { if(a[i]!='+') sb+=a[i],lb++; } else sa+=a[i],la++; } if(sadd.size()==0 && smultiply.size()==0 && s.size()==0) printf("No changes "); else { if(sadd.size()>0) { ok=0; for(it=sadd.begin();it!=sadd.end();it++) { printf("%c",ok==1?',':'+'); cout<<*it;ok=1; } printf(" "); } if(s.size()>0) { ok=0; for(it=s.begin();it!=s.end();it++) { printf("%c",ok==1?',':'-'); cout<<*it;ok=1; } printf(" "); } if(smultiply.size()>0) { ok=0; for(it=smultiply.begin();it!=smultiply.end();it++) { printf("%c",ok==1?',':'*'); cout<<*it;ok=1; } printf(" "); } printf(" "); } s.clear(); sadd.clear(); smultiply.clear(); m.clear(); } return 0; } /* 4 {X:+123,VYVG:NNNJ} {X:123,VYVG:NNNJ} {:123,bgb:456,k:789} {:124,bgb:123,k:789} {:123,bgb:456,k:789} {:123,bgb:452} {:,xx:xx} {xx:xx} */ /* No changes *,bgb -k *bgb No changes */
E:最短的名字
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 简单字典树判断
#include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <vector> #include <queue> #include <cstdlib> #include <iomanip> #include <cmath> #include <ctime> #include <map> #include <set> using namespace std; #define lowbit(x) (x&(-x)) #define max(x,y) (x>y?x:y) #define min(x,y) (x<y?x:y) #define MAX 100000000000000000 #define MOD 1000000007 #define pi acos(-1.0) #define ei exp(1) #define PI 3.141592653589793238462 #define ios() ios::sync_with_stdio(false) #define INF 1044266558 #define mem(a) (memset(a,0,sizeof(a))) typedef long long ll; char a[1005][10009]; int t,n; struct trie { int cnt; int len; struct trie *next[27]; trie() { cnt=0; len=0; for(int i=0;i<26;i++) next[i]=NULL; } }; trie *root; void insert(trie *root,char *s) { int len=strlen(s); trie *p=root,*tmp; for(int i=0;i<len;i++) { if(p->next[s[i]-'a']==NULL) { tmp=new trie(); p->next[s[i]-'a']=tmp; } p=p->next[s[i]-'a']; p->len=i+1; p->cnt++; } } int find(trie *root,char *s) { int len=strlen(s); trie *p=root; for(int i=0;i<len;i++) { if(p->next[s[i]-'a']==NULL) return 0; p=p->next[s[i]-'a']; if(p->cnt==1) return p->len; } } int main() { scanf("%d",&t); while(t--) { root=new trie(); scanf("%d",&n); int ans=0; for(int i=0;i<n;i++) { scanf("%s",&a[i]); insert(root,a[i]); } for(int i=0;i<n;i++) ans+=find(root,a[i]); printf("%d ",ans); } return 0; }
F:Kingdoms
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
要点是必须包含首都即城市1,然后不超过k,人口又尽可能多,刚开始以为是背包,搞不来,一看数据量很小2^15,枚举最小生成树就可以了,这里枚举的是标记路径
#include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <vector> #include <queue> #include <cstdlib> #include <iomanip> #include <cmath> #include <ctime> #include <map> #include <set> using namespace std; #define lowbit(x) (x&(-x)) #define max(x,y) (x>y?x:y) #define min(x,y) (x<y?x:y) #define MAX 100000000000000000 #define MOD 1000000007 #define pi acos(-1.0) #define ei exp(1) #define PI 3.141592653589793238462 #define ios() ios::sync_with_stdio(false) #define INF 1044266558 #define mem(a) (memset(a,0,sizeof(a))) typedef long long ll; int g[20][20],n,m,k; int vis[20],dis[20]; int pos[20],por[20],ans,cont; int x,y,z,t; void init() { for(int i=0;i<=n;i++) { for(int j=0;j<=i;j++) { g[i][j]=g[j][i]=(i==j?0:INF); } } } int dij() { for(int i=1;i<=n;i++) { dis[i]=g[1][i]; vis[i]=0; } vis[1]=1; int v,maxn,inf=0; for(int i=1;i<=n;i++) { maxn=INF; for(int j=1;j<=n;j++) { if(!vis[j] && pos[j] && maxn>dis[j]) { maxn=dis[j]; v=j; } } if(maxn==INF) break; vis[v]=1; inf+=maxn; for(int j=1;j<=n;j++) { if(!vis[j] && pos[j]) dis[j]=min(g[v][j],dis[j]); } } for(int i=1;i<=n;i++) { if(vis[i]!=pos[i]) return INF; } return inf; } void dfs(int cnt) { if(cnt>n) { if(dij()<=k) { cont=0; for(int i=1;i<=n;i++) { if(pos[i]) cont+=por[i]; } ans=max(ans,cont); } return ; } for(int i=0;i<=1;i++) { pos[cnt]=i; dfs(cnt+1); } } int main() { scanf("%d",&t); while(t--) { scanf("%d%d%d",&n,&m,&k); init(); for(int i=1;i<=n;i++) scanf("%d",&por[i]); for(int i=0;i<m;i++) { scanf("%d%d%d",&x,&y,&z); g[x][y]=g[y][x]=min(g[x][y],z); } ans=por[1]; pos[1]=true; dfs(2); printf("%d ",ans); } return 0; }
I:Collecting Coins
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
英语差的弱点一下就暴露了,那么多的细节一开始没反应过来,题看了好久才懂什么意思,收集金币,收集过后此地为空,开始坐标走过后为空,中间可能碰到障碍
或者岩石,但岩石可以移动,且每块岩石最多被移动一次,且只能往前进的方向移动,典型的搜索类题型,但有岩石不好搜索,可以先深搜一遍,然后再从岩石处搜索
因为开始的搜索已被标记,不用担心重复,之后两者之和即为解。
#include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <vector> #include <queue> #include <cstdlib> #include <iomanip> #include <cmath> #include <ctime> #include <map> #include <set> using namespace std; #define lowbit(x) (x&(-x)) #define max(x,y) (x>y?x:y) #define min(x,y) (x<y?x:y) #define MAX 100000000000000000 #define MOD 1000000007 #define pi acos(-1.0) #define ei exp(1) #define PI 3.141592653589793238462 #define ios() ios::sync_with_stdio(false) #define INF 1044266558 #define mem(a) (memset(a,0,sizeof(a))) typedef long long ll; int dir[4][2]={{1,0},{0,-1},{0,1},{-1,0}}; int t,n,m,ans,pos,k,cnt,inf; int vis[105][105],cont; char a[105][105]; struct Node { int x; int y; int mark; Node(int a,int b,int c):x(a),y(b),mark(c){} Node(){} }node[8]; int check(int x,int y) { if(x<0 || x>=n || y<0 || y>=m) return 0; return 1; } void dfs(int x,int y,int flag) { vis[x][y]=flag; for(int i=0;i<4;i++) { int nx=x+dir[i][0]; int ny=y+dir[i][1]; if(!check(nx,ny) || a[nx][ny]=='X' || vis[nx][ny] || a[nx][ny]=='O') continue; if(a[nx][ny]=='C') cnt++; dfs(nx,ny,flag); } } void backtrack(int x,int y,int flag) { vis[x][y]=0; for(int i=0;i<4;i++) { int nx=x+dir[i][0]; int ny=y+dir[i][1]; if(!check(nx,ny) || vis[nx][ny]!=flag) continue; backtrack(nx,ny,flag); } } void solve(int x) { if(x>=k || pos+inf==ans) return; for(int i=0;i<k && pos+inf<ans;i++) { if(node[i].mark) continue; node[i].mark=1; for(int j=0;j<4;j++) { int nx=node[i].x+dir[j][0],ny=node[i].y+dir[j][1]; if(!check(nx,ny) || a[nx][ny]=='X' || !vis[nx][ny]) continue;//是否可以站人 nx=node[i].x-dir[j][0],ny=node[i].y-dir[j][1];//朝面对的那个方向推 if(!check(nx,ny) || a[nx][ny]!='.') continue; a[nx][ny]='X',a[node[i].x][node[i].y]='.'; cnt=0; dfs(node[i].x,node[i].y,i+3); cont+=cnt; int t=cnt; solve(x+1); inf=max(cont,inf); backtrack(node[i].x,node[i].y,i+3); cont-=t; a[nx][ny]='.',a[node[i].x][node[i].y]='O'; } node[i].mark=0; } } int main() { scanf("%d",&t); while(t--) { int ax,by; scanf("%d%d",&n,&m); k=0;ans=0;pos=0; for(int i=0;i<n;i++) { scanf("%s",&a[i]); for(int j=0;j<m;j++) { if(a[i][j]=='S') ax=i,by=j,a[i][j]='.'; else if(a[i][j]=='O') node[k++]=Node(i,j,0); else if(a[i][j]=='C') ans++; } } memset(vis,0,sizeof(vis)); cnt=0;inf=0,cont=0; dfs(ax,by,1); pos=cnt; solve(0); pos+=inf; printf("%d ",pos); } return 0; }
J:病毒
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
刚开始只是简单的以为两次最长子序列然后去最小就可以了,无限wa,最后才发现这样顺序不能保证,所以是最长上升公共子序列,dp一下就可以了
#include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <vector> #include <queue> #include <cstdlib> #include <iomanip> #include <cmath> #include <ctime> #include <map> #include <set> using namespace std; #define lowbit(x) (x&(-x)) #define max(x,y) (x>y?x:y) #define min(x,y) (x<y?x:y) #define MAX 100000000000000000 #define MOD 1000000007 #define pi acos(-1.0) #define ei exp(1) #define PI 3.141592653589793238462 #define ios() ios::sync_with_stdio(false) #define INF 1044266558 #define mem(a) (memset(a,0,sizeof(a))) typedef long long ll; int a[1006],b[1006],dp[1006]; int n,m,t,ans; int solve() { scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d",&a[i]); scanf("%d",&m); for(int i=0;i<m;i++) scanf("%d",&b[i]); memset(dp,0,sizeof(dp)); for(int i=0;i<n;i++) { ans=0; for(int j=0;j<m;j++) { if(a[i]>b[j]) ans=max(ans,dp[j]); if(a[i]==b[j]) dp[j]=ans+1; } } ans=0; for(int i=0;i<m;i++) { ans=max(ans,dp[i]); } return ans; } int main() { scanf("%d",&t); while(t--) { printf("%d ",solve()); } return 0; }