http://acm.csu.edu.cn/OnlineJudge/problem.php?cid=2101&pid=6
题意:
狗追小偷,如果找到了他的足迹,则速度变为原来2倍,有若干个出口,问最后小偷能否顺利逃脱。
思路:
枚举每一个出口,从小偷开始bfs,如果下一个点满足条件(小偷到这个点的距离+到出口距离<狗到这个点距离+到出口距离+1 /2) 则可以转移,如果能转移到出口则可以逃脱~
#include <stdio.h>
int grid_width, grid_height;
char grid_sym[2510];
int grid_dist_kennel[2500];
int grid_dist_thief[2500];
int grid_dist_exit[2500];
int exits[200];
#define FFQC 2510
int ffq_pop_idx = 0, ffq_push_idx = 0;
int ffqp[FFQC], ffqd[FFQC];
void ffq_push(int pos, int depth) {
ffqp[ffq_push_idx] = pos;
ffqd[ffq_push_idx] = depth;
ffq_push_idx = (ffq_push_idx + 1) % FFQC;
}
int ffq_pop(int *pos, int *depth) {
if (ffq_pop_idx == ffq_push_idx) return 0;
*pos = ffqp[ffq_pop_idx];
*depth = ffqd[ffq_pop_idx];
ffq_pop_idx = (ffq_pop_idx + 1) % FFQC;
return 1;
}
void flood_fill(int start_pos, int *distances, int(*should_visit)(int, int)) {
for (int i = 0; i < 2500; ++i) {
distances[i] = -1;
}
ffq_push(start_pos, 0);
int pos, depth;
while (ffq_pop(&pos, &depth)) {
if (distances[pos] == -1 && grid_sym[pos] != 'X' && should_visit(pos, depth)) {
distances[pos] = depth;
const int row = pos / grid_width;
const int col = pos % grid_width;
if (row > 0) ffq_push(pos - grid_width, depth + 1);
if (col > 0) ffq_push(pos - 1, depth + 1);
if (col + 1 < grid_width) ffq_push(pos + 1, depth + 1);
if (row + 1 < grid_height) ffq_push(pos + grid_width, depth + 1);
}
}
}
int should_visit_thief(int pos, int depth) {
const int thief_exit_time = depth + grid_dist_exit[pos];
const int dog_exit_time = grid_dist_kennel[pos] + (grid_dist_exit[pos] + 1) / 2;
return thief_exit_time < dog_exit_time;
}
int should_visit_other(int pos, int depth) {
return 1;
}
void handle_case() {
int thief, kennel, num_exits = 0;
for (int i = grid_width * grid_height; i > 0; --i) {
switch (grid_sym[i]) {
case 'T': thief = i; break;
case 'K': kennel = i; break;
case 'E': exits[num_exits++] = i;
}
}
flood_fill(kennel, grid_dist_kennel, should_visit_other);
for (int i = 0; i < num_exits; ++i) {
flood_fill(exits[i], grid_dist_exit, should_visit_other);
flood_fill(thief, grid_dist_thief, should_visit_thief);
if (grid_dist_thief[exits[i]] >= 0) {
puts("KEEP IT");
return;
}
}
puts("DROP IT");
}
int main() {
while (scanf("%d %d ", &grid_width, &grid_height) == 2 && grid_width >= 3 && grid_height >= 3) {
for (int row = 0; row < grid_height; ++row) {
fgets(&grid_sym[row * grid_width], 60, stdin);
}
handle_case();
}
}
http://acm.csu.edu.cn/OnlineJudge/problem.php?cid=2101&pid=0
题意: 一棵满二叉树代表一个家谱,定义几种成员关系,任意给定2个序号和b的性别,问a和b的关系。
找到最近公共祖先,根据a 到最近公共祖先的距离和a与b的距离之差即可判断出到底是什么关系,最近公共祖先只要找规律去求即可~
#include <stdio.h>
char *nth[] = {"1st", "2nd", "3rd"};
char *removed[] = {"once", "twice", "thrice"};
#define MF(m, f) sex == 'M' ? m : f
void handle_case(int id_a, int id_b, char sex) {
int dist_a = 0, dist_b = 0;
while (id_a != id_b) {
if (id_a > id_b) dist_a++, id_a = (id_a - 1) / 2;
else dist_b++, id_b = (id_b - 1) / 2;
}
int smaller = dist_a < dist_b ? dist_a : dist_b;
int delta = dist_a - smaller + dist_b - smaller;
if (dist_a == 0 && dist_b == 0) {
puts("self");
} else if (dist_a == 1 && dist_b == 1) {
puts(MF("brother", "sister"));
} else if (smaller <= 1 && delta <= 4) {
switch (delta) {
case 4: fputs("great-", stdout);
case 3: fputs("great-", stdout);
case 2: fputs("grand", stdout);
}
if (dist_a == 0) puts(MF("son", "daughter"));
else if (dist_b == 0) puts(MF("father", "mother"));
else if (dist_a == 1) puts(MF("nephew", "niece"));
else puts(MF("uncle", "aunt"));
} else if (smaller >= 2 && smaller <= 4 && delta <= 3) {
if (delta == 0) printf("%s cousin\n", nth[smaller - 2]);
else printf("%s cousin %s removed\n", nth[smaller - 2], removed[delta - 1]);
} else {
puts("kin");
}
}
int main(int argc, char** argv) {
int id_a, id_b;
char sex;
while (scanf("%d %d %c", &id_a, &id_b, &sex) && id_a >= 0) {
handle_case(id_a, id_b, sex);
}
return 0;
}
B:二分答案
#include <math.h>
#include <stdio.h>
int main() {
double pi = acos(-1);
double precision = 0.00001 * pi / 180;
double d, h, x, n1, n2;
while (scanf("%lf %lf %lf %lf %lf", &d, &h, &x, &n1, &n2) && d) {
double phi_min = 0;
double phi_max = pi / 2;
while (phi_max - phi_min > precision) {
double phi = (phi_min + phi_max) / 2;
double theta1 = pi / 2 - phi;
double theta2 = asin(n2 * sin(theta1) / n1);
if (d * tan(theta1) + h * tan(theta2) > x) {
phi_min = phi;
} else {
phi_max = phi;
}
}
printf("%0.02lf\n", phi_min * 180 / pi);
}
}
暴力,注意字典序的排序方法以及字符串从1开始的递归终止条件是>长度 !!!!!
#include <bits/stdc++.h>
using namespace std;
char d[250][30],s[10][10];
int w,dd;char m[10][10];
int dir[8][2]={1,0,-1,0,0,1,0,-1,1,1,1,-1,-1,1,-1,-1};
struct Geng
{
char s[30];
}ans[250];
bool cmp(Geng g1,Geng g2){
int l = 0;
for(int i = 0 ; g1.s[i] != '\0' && g2.s[i] != '\0' ; i++) {
if(g1.s[i] != g2.s[i]) return g1.s[i] < g2.s[i];
l = i;
}
int l1, l2;
l1 = l2 = l + 1;
if(g1.s[l + 1] != '\0') l1++;
if(g2.s[l + 1] != '\0') l2++;
return l1 < l2;
}
int find(char s[10][10],char *d,int x,int y,int pos){
if(pos>strlen(d+1)){
return 1;
}
char now=s[x][y];
s[x][y]='0';
for(int i=0;i<8;i++){
int nx=x+dir[i][0];
int ny=y+dir[i][1];
if(s[nx][ny]=='q'){
if(strlen(d+pos)>=2&&d[pos]=='q'&&d[pos+1]=='u'){
if(find(s,d,nx,ny,pos+2)){
return 1;
}
}
}
else if(s[nx][ny]==d[pos]){
if(find(s,d,nx,ny,pos+1)){
return 1;
}
}
}
s[x][y]=now;
return 0;
}
int main(){
scanf("%d",&w);
for(int i=1;i<=w;i++){
scanf("%s",d[i]+1);
}
while(scanf("%d",&dd)!=EOF){
if(dd==0) break;
for(int i=0;i<=8;i++){
for(int j=0;j<=8;j++){
s[i][j]='0';
}
}
for(int i=1;i<=dd;i++){
scanf("%s",s[i]+1);
}
for(int i=1;i<=dd;i++){
for(int j=1;j<=strlen(s[i]+1);j++){
m[i][j]=s[i][j];
}
}
int kk=0;
for(int i=1;i<=w;i++){
int flag=0;
for(int j=1;j<=dd;j++){
for(int k=1;k<=dd;k++){
if(s[j][k]=='q'){
if(strlen(d[i]+1)>=2&&d[i][1]=='q'&&d[i][2]=='u'){
for(int i1=1;i1<=dd;i1++){
for(int j1=1;j1<=strlen(s[i1]+1);j1++){
m[i1][j1]=s[i1][j1];
}
}
if(find(m,d[i],j,k,3)){
strcpy(ans[kk++].s,d[i]+1);flag=1;break;
}
}
}
else if(s[j][k]==d[i][1]){
for(int i1=1;i1<=dd;i1++){
for(int j1=1;j1<=strlen(s[i1]+1);j1++){
m[i1][j1]=s[i1][j1];
}
}
if(find(m,d[i],j,k,2)){
strcpy(ans[kk++].s,d[i]+1);flag=1;break;
}
}
}
if(flag) break;
}
}
// for(int i = 0 ; i < kk ; i++) printf("%s\n", ans[i].s);
// rp
sort(ans,ans+kk,cmp);
for(int i=0;i<kk;i++){
printf("%s\n",ans[i].s);
}
puts("-");
}
}
/*
1
rprquit
5
rprit
ahqln
ietep
zrysg
ogwey
0
*/
/**************************************************************
Problem: 1719
User: ALPC_t_1
Language: C++
Result: Accepted
Time:0 ms
Memory:1508 kb
****************************************************************/
没想到这题用string写还是蛮方便的,直接暴力查询就好了,不用像char那样先匹配到一起,然后再整体比对,substr函数第一个是首指针,第二个是长度,可以直接取出来这个substr 判断是不是与字典相等即可~~
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 300;
const int MAXM = 1000 + 5;
int m;
string allot[MAXM];
map<char, string> ma;
char str1[MAXM];
string str2;
void init()
{
ma.clear();
for(int i = 0 ; i < 26 ; i++) {
char u = i + 'A';
scanf("%s", str1);
cin>>str2;
ma[u] = str2;
}
scanf("%d", &m);
for(int i = 0 ; i < m ; i++) cin >> allot[i];
}
string data[MAXM];
string out[MAXM];
string match(string u)
{
for(int i = 0 ; i < m ; i++) {
int ok = 1;
int now = 0;
for(int j = 0 ; j < allot[i].size() ; j++) {
int len = ma[allot[i][j]].size();
if(u.substr(now, len) != ma[allot[i][j]]) {
ok = 0;
break;
}
else now += len;
if(now > u.size()) {
ok = 0;
break;
}
}
if(now != u.size()) ok = 0;
if(ok == 1) return allot[i];
}
return "-1";
}
int main()
{
init();
int n;
while(scanf("%d", &n) != EOF && n) {
int flag = 1;
int pos;
for(int i = 0 ; i < n ; i++) {
cin >> data[i];
out[i] = match(data[i]);
if(out[i] == "-1") {
if(flag == 1) {
pos = i;
flag = 0;
}
}
}
if(flag == 0) {
cout << data[pos] << " not in dictionary.\n";
continue;
}
for(int i = 0 ; i < n ; i++) {
if(i) cout << " ";
cout << out[i] ;
}
printf("\n");
}
return 0;
}