A. Shortest path of the king
题目地址:http://codeforces.com/contest/3/problem/A
题目大意:求8*8的棋盘上一个点到还有一个点的最短路径。
算法讨论:优先斜着走,走到同一直线后直着走。
Code:
#include <cstdio>
#define N 10000
using namespace std;
char c,ch;
int x1,y1,x2,y2,ans,a[N+10];
char get(){
while (!(c>='0' && c<='9' || c>='a' && c<='h')) c=getchar();
char tc=c;
c=getchar();
return tc;
}
int main(){
ch=get();
x1=ch-'a'+1;
ch=get();
y1=ch-'0';
ch=get();
x2=ch-'a'+1;
ch=get();
y2=ch-'0';
//L-1
//R-2
//U-3
//D-4
//LU-5
//LD-6
//RU-7
//RD-8
while (x1<x2 && y1<y2) a[ans++]=7,x1++,y1++;
while (x1<x2 && y1>y2) a[ans++]=8,x1++,y1--;
while (x1>x2 && y1>y2) a[ans++]=6,x1--,y1--;
while (x1>x2 && y1<y2) a[ans++]=5,x1--,y1++;
while (x1<x2) a[ans++]=2,x1++;
while (x1>x2) a[ans++]=1,x1--;
while (y1<y2) a[ans++]=3,y1++;
while (y1>y2) a[ans++]=4,y1--;
printf("%d
",ans);
for (int i=0;i<ans;++i)
switch (a[i]){
case 1:printf("L
");break;
case 2:printf("R
");break;
case 3:printf("U
");break;
case 4:printf("D
");break;
case 5:printf("LU
");break;
case 6:printf("LD
");break;
case 7:printf("RU
");break;
case 8:printf("RD
");break;
}
return 0;
}
B. Lorry
题目地址:http://codeforces.com/contest/3/problem/B
题目大意:有n个物品。体积仅仅可能为1或2。每一个物品有一个体积。在给定v体积内,问最大价值是多少。
算法讨论:
假设没有体积1和2的限制,那么就是01背包问题。可是题中n达到10^5。v达到10^9。O(n*v)的复杂度显然不可行。
然后考虑体积1和2的限制。我们最好还是将体积为1的和体积为2的物品分别储存,然后分别排序。
枚举体积为1的物品的个数,那么能够计算出体积为2的物品的个数。将当前价值更新答案就可以。
Code:
#include <cstdio>
#include <algorithm>
#define N 100000
using namespace std;
int n,v,t,p,ones,twos,value,ans,cnt;
struct node{
int value,id,sum;
}one[N+10],two[N+10];
inline bool cmp(node a,node b){
return a.value>b.value;
}
int main(){
scanf("%d%d",&n,&v);
for (int i=1;i<=n;++i){
scanf("%d%d",&t,&p);
if (t==1) ones++,one[ones].value=p,one[ones].id=i;
else twos++,two[twos].value=p,two[twos].id=i;
}
sort(one+1,one+ones+1,cmp);
sort(two+1,two+twos+1,cmp);
for (int i=1;i<=ones;++i) one[i].sum=one[i-1].sum+one[i].value;
for (int i=1;i<=twos;++i) two[i].sum=two[i-1].sum+two[i].value;
for (int i=0,lim=min(ones,v);i<=lim;++i){
value=one[i].sum+two[min((v-i)/2,twos)].sum;
if (value>ans) ans=value,cnt=i;
}
printf("%d
",ans);
for (int i=1;i<=cnt;++i) printf("%d ",one[i].id);
for (int i=1,lim=min((v-cnt)/2,twos);i<=lim;++i) printf("%d ",two[i].id);
puts("");
return 0;
}
C. Tic-tac-toe
题目地址:http://codeforces.com/contest/3/problem/C
题目大意:给出一个三子棋的局面。问当前状态。
算法讨论:模拟,注意特判。
Code:
#include <cstdio>
using namespace std;
char s[3][3];
int a,b;
bool A,B;
inline int abs(int x){return x>0?x:-x;}
int main(){
scanf("%s",s[0]);
scanf("%s",s[1]);
scanf("%s",s[2]);
for (int i=0;i<3;++i)
for (int j=0;j<3;++j)
if (s[i][j]=='X') a++;
else if (s[i][j]=='0') b++;
if (s[0][0]=='X' && s[0][1]=='X' && s[0][2]=='X' ||
s[1][0]=='X' && s[1][1]=='X' && s[1][2]=='X' ||
s[2][0]=='X' && s[2][1]=='X' && s[2][2]=='X' ||
s[0][0]=='X' && s[1][0]=='X' && s[2][0]=='X' ||
s[0][1]=='X' && s[1][1]=='X' && s[2][1]=='X' ||
s[0][2]=='X' && s[1][2]=='X' && s[2][2]=='X' ||
s[0][0]=='X' && s[1][1]=='X' && s[2][2]=='X' ||
s[0][2]=='X' && s[1][1]=='X' && s[2][0]=='X') A=1;
if (s[0][0]=='0' && s[0][1]=='0' && s[0][2]=='0' ||
s[1][0]=='0' && s[1][1]=='0' && s[1][2]=='0' ||
s[2][0]=='0' && s[2][1]=='0' && s[2][2]=='0' ||
s[0][0]=='0' && s[1][0]=='0' && s[2][0]=='0' ||
s[0][1]=='0' && s[1][1]=='0' && s[2][1]=='0' ||
s[0][2]=='0' && s[1][2]=='0' && s[2][2]=='0' ||
s[0][0]=='0' && s[1][1]=='0' && s[2][2]=='0' ||
s[0][2]=='0' && s[1][1]=='0' && s[2][0]=='0') B=1;
if (A && B || a<b || A && a==b || B && a>b || abs(a-b)!=0 && abs(a-b)!=1){printf("illegal
");return 0;}
if (A){printf("the first player won
");return 0;}
if (B){printf("the second player won
");return 0;}
if (a+b==9){printf("draw");return 0;}
if (a==b) printf("first
");else printf("second
");
return 0;
}
D. Least Cost Bracket Sequence
题目地址:http://codeforces.com/contest/3/problem/D
题目大意:给定一个括号序列,有些位置是未知的,未知位置填左右括号分别有一定代价,问使序列合法的最小代价是多少。
算法讨论:假设全部的?都是)。然后从左到右检验括号是否匹配,假设不匹配则花费最小的代价将之前的一个?改成(。
Code:
#include <cstdio>
#include <cstring>
#include <queue>
#define N 1000000
using namespace std;
char s[N+10];
int l,cnt,x,y;
long long ans;
struct node{
int key,id;
};
bool operator <(node a,node b){
return a.key<b.key;
}
priority_queue<node> Q;
int main(){
scanf("%s",s);
l=strlen(s);
for (int i=0;i<l;++i){
switch (s[i]){
case '(':cnt++;break;
case ')':cnt--;break;
case '?':
scanf("%d%d",&x,&y);
s[i]=')';
cnt--;
ans+=(long long)y;
Q.push((node){y-x,i});
break;
}
if (cnt<0){
if (Q.empty()){printf("-1
");return 0;}
ans-=(long long)Q.top().key;
s[Q.top().id]='(';
Q.pop();
cnt+=2;
}
}
if (cnt) printf("-1
");
else printf("%I64d
",ans),printf("%s
",s);
return 0;
}
By Charlie Pan
Mar 9,2014