ACM Summer Training Warm up
热身水题
题目
HDU 4500 小Q系列故事——屌丝的逆袭
思路
简单的模拟,一个数组读入数据,一个数组计算维护结果
#include
#include
#include
using namespace std;
int n,m,x,y,Max,map[22][22],s[22][22];
int main()
{
while(scanf("%d %d",&n,&m))
{
if(n == 0 && m == 0)
break;
memset(map,0,sizeof(map));
memset(s,0,sizeof(s));
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
scanf("%d",&map[i][j]);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
{
if(map[i][j] * map[i-1][j] < 0)
s[i][j] += abs(map[i-1][j]);
else
s[i][j] -= abs(map[i-1][j]);
if(map[i][j] * map[i+1][j] < 0)
s[i][j] += abs(map[i+1][j]);
else
s[i][j] -= abs(map[i+1][j]);
if(map[i][j] * map[i][j-1] < 0)
s[i][j] += abs(map[i][j-1]);
else
s[i][j] -= abs(map[i][j-1]);
if(map[i][j] * map[i][j+1] < 0)
s[i][j] += abs(map[i][j+1]);
else
s[i][j] -= abs(map[i][j+1]);
}
Max = -9999;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
if(s[i][j] > Max)
{
x = i;
y = j;
Max = s[i][j];
}
printf("%d %d %d\n",x,y,Max);
}
return 0;
}
HDU 2109 Fighting for HDU
思路
简单排序,sort()
#include
#include
using namespace std;
int n,a[110],b[110];
int main()
{
while(scanf("%d",&n) && n)
{
a[0] = 0; b[0] = 0;
for(int i = 1; i <= n; i++)
scanf("%d",&a[i]);
for(int i = 1; i <= n; i++)
scanf("%d",&b[i]);
sort(a+1,a+1+n);
sort(b+1,b+1+n);
for(int i = 1; i <= n; i++)
if(a[i] > b[i])
a[0] += 2;
else
if(a[i] < b[i])
b[0] += 2;
else
a[0] += 1,b[0] += 1;
printf("%d vs %d\n",a[0],b[0]);
}
return 0;
}
HDU 2111 Saving HDU
思路
贪心+排序,优先对单价进行排序
#include
#include
using namespace std;
struct goods
{
double v;
double p;
double r;
}g[110];
int v,n,sum;
bool cmp(goods x,goods y)
{
return x.p > y.p;
}
int main()
{
while(scanf("%d%d",&v,&n) && v)
{
sum = 0;
for(int i = 0; i < n; i++)
{
scanf("%lf%lf",&g[i].p,&g[i].v);
g[i].r = g[i].p / g[i].v;
}
sort(g,g+n,cmp);
for(int i = 0; i < n; i++)
if(v >= g[i].v)
v -= g[i].v, sum += g[i].p * g[i].v;
else
{
sum += v * g[i].p;
break;
}
printf("%d\n",sum);
}
return 0;
}
HDU 3787 A+B
思路
字符串转整形再进行求和即可
#include
#include
using namespace std;
int x,y,l;
char s1[20],s2[20];
bool f;
int main()
{
while(scanf("%s%s",s1,s2)!=EOF)
{
getchar();
l = strlen(s1);
x = 0; y = 0;
for(int i = 0; i < l; i++)
if(s1[i] >= '0' && s1[i] <= '9')
x = x * 10 + (s1[i] - '0');
l = strlen(s2);
for(int i = 0; i < l; i++)
if(s2[i] >= '0' && s2[i] <= '9')
y = y * 10 + (s2[i] - '0');
if(s1[0] == '-')
x = -x;
if(s2[0] == '-')
y = -y;
printf("%d\n",x+y);
}
return 0;
}
HDU 2108 Shape of HDU
思路
遍历所有的点,任意连续三点构成两个向量,根据向量相乘的结果,大于等于0为凸多边形(锐角和直角),小于0为凹多边形(钝角)
#include
using namespace std;
struct angle
{
int x;
int y;
}a[1010];
int n;
bool f,r;
bool judge(angle a,angle b,angle c)
{
return ((c.y - a.y) * (b.x-a.x) - (c.x - a.x) * (b.y - a.y) ) < 0 ;
}
int main()
{
while(scanf("%d",&n) && n)
{
f = true; r = true;
for(int i = 0; i < n; i++)
scanf("%d%d",&a[i].x,&a[i].y);
for(int i = 0; i < n; i++)
{
if(i == 0)
r = judge(a[0],a[1],a[n - 1]);
else
if(i == n - 1)
r = judge(a[n - 1],a[0],a[n - 2]);
else
r = judge(a[i],a[i + 1],a[i - 1]);
if(r)
{
f = false;
printf("concave\n");
break;
}
}
if(f)
printf("convex\n");
}
return 0;
}
HDU 3783 ZOJ
思路
读入字符串,把zoj三个字母分别存起来,输出时候按照zoj数目依次顺序输出
#include
#include
using namespace std;
char s[110],s1[4] = {"ZOJ"};
int a[4];
int main()
{
while(scanf("%s",s)!=EOF)
{
if(s[0] == 'E')
break;
memset(a,0,sizeof(a));
for(int i = 0; i < strlen(s); i++)
if(s[i] == 'Z')
a[0]++;
else
if(s[i] == 'O')
a[1]++;
else
a[2]++;
for(int i = 0; i < 3; i++)
while(a[i])
{
a[i]--;
printf("%c",s1[i]);
for(int j = i+1; j < 3; j++)
if(a[j])
a[j]--,printf("%c",s1[j]);
}
printf("\n");
}
return 0;
}
HDU 3784 继续xxx定律
思路
3n+1定理,多加一个数组判断当前结果是否出现过,最后输出
#include
#include
#define M 300010
using namespace std;
int n,t,a[M];
bool m[M],f;
int main()
{
while(scanf("%d",&n)!=EOF && n)
{
memset(a,0,sizeof(a));
memset(m,1,sizeof(m));
f = true;
for(int i = 0; i < n; i++)
scanf("%d",&a[i]);
for(int i = 0; i < n; i++)
if(!m[a[i]])
continue;
else
{
t = a[i];
while(t > 1)
{
t = t % 2 == 0 ? t/=2 : (t * 3 + 1)/2;
m[t] = false;
}
}
for(int i = n-1; i>= 0; i--)
if(m[a[i]] && f)
{
f = false;
printf("%d",a[i]);
}
else
if(m[a[i]])
printf(" %d",a[i]);
printf("\n");
}
return 0;
}
HDU 3788 ZOJ问题
思路
找规律,z前面o的个数乘以z和j之间的o的个数等于j后面o的个数
#include
#include
using namespace std;
char s[1010];
int a[3],p1,p2,x,y,z;
int main()
{
while(scanf("%s",s)!=EOF)
{
memset(a,0,sizeof(a));
x = 0; y = 0; z = 0;
for(int i = 0,j = 0; i < strlen(s); i++)
if(s[i] == 'z')
p1 = i,x++;
else
if(s[i] == 'j')
{
p2 = i,y++;
}
else
z++;
if(!x || !y || !z)
{
printf("Wrong Answer\n");
continue;
}
else
{
for(int i = 0; i < p1; i++)
a[0]++;
for(int i = p1 + 1; i < p2; i++)
a[1]++;
for(int i = p2 + 1; i < strlen(s); i++)
a[2]++;
}
if(a[0] * a[1] == a[2])
printf("Accepted\n");
else
printf("Wrong Answer\n");
}
return 0;
}
POJ 1002 487-3279
题目描述
给你一组数字或者字符串形式的电话号码,根据题目字母转换表要求进行转换成数字,统计每个电话号码出现次数,最后根据字典序和规定格式输出。
思路
简单的字符串转换数字,然后对数字进行排序,从小到大统计输出
#include
#include
#include
using namespace std;
char str[2010];
int n,i,j,l,sum,a[100010],map[26] = {2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,0,7,7,8,8,8,9,9,9};
bool f;
int main()
{
scanf("%d",&n);
getchar();
j = 0; f = true;
memset(a,0,sizeof(a));
while(n--)
{
scanf("%s",str);
l = strlen(str);
for(i = 0; i < l; i++)
if(str[i] == '-')
continue;
else
if(str[i] >= 'A' && str[i] <= 'Z')
a[j] = a[j] * 10 + map[(str[i] - 'A')];
else
a[j] = a[j] * 10 + (str[i] - '0');
j++;
}
sort(a,a+j);
for(i = 0,sum = 1; i < j; i++)
if(a[i] == a[i+1])
sum++;
else
if(sum > 1)
{
printf("%03d-%04d %d\n",a[i]/10000,a[i]%10000,sum);
f = false;
sum = 1;
}
else
sum = 1;
if(f)
printf("No duplicates.\n");
return 0;
}
HDU 1001 Sum Problem
题目描述
计算n!
思路
可以用高精度乘法模拟实现,或者暴力方法,根据等差数列求和公式,先除以2再乘以n+1,防止溢出
#include
using namespace std;
double n;
int main()
{
while(scanf("%lf",&n)!=EOF)
{
printf("%0.lf\n\n",n/2*(1+n));
}
return 0;
}
HDU 1016 Prime Ring Problem
题目描述
给你1~n构成一个素数环,相邻两个的和是素数
思路
先打表记录素数,然后深度搜索,以当前选择了几个数为状态,当前选择个数是否大于n作为边界条件,最后用数组保存维护结果
#include
#include
#include
using namespace std;
const int M = 10010;
int c,n,a[M];
bool vis[M],prime[M];
void dfs(int num)
{
if(num > n && !prime[a[1] + a[num-1]])
{
printf("%d",a[1]);
for (int j = 2; j <= n; j++)
printf(" %d",a[j]);
printf("\n");
return ;
}
for (int i = 2; i <= n; i++)
{
if(!vis[i] && !prime[i + a[num-1]])
{
vis[i] = 1;
a[num++] = i;
dfs(num);
vis[i] = 0;
num--;
}
}
return ;
}
int main()
{
memset(prime,0,sizeof(prime));
prime[1] = 1;
for (int i = 2; i <= 100; i++)
if(!prime[i])
for (int j = i + i; j <= 100; j+=i)
prime[j] = 1;
while(cin>>n)
{
memset(vis,0,sizeof(vis));
a[1] = 1;
vis[1] = 1;
printf("Case %d:\n",++c);
dfs(2);
printf("\n");
}
return 0;
}
HDU 2612 Find a way
题目描述
Y和M要去麦当劳@约会,问两个人到达同一个麦当劳的距离和最短是多少
思路
分别对Y和M进行广度搜索,最后遍历图上的麦当劳位置输出最短距离
#include
#include
#include
#include
using namespace std;
const int M = 210;
const int inf = 0xffffff;
struct node
{
int x,y,step;
};
int n,m,f,ans,step[M][M][2],dir[4][2]={1,0,0,1,-1,0,0,-1};
char map[M][M];
bool vis[M][M];
void bfs(int x,int y)
{
node curr,next;
curr.x = x;
curr.y = y;
curr.step = 0;
queue Q;
Q.push(curr);
while(!Q.empty())
{
curr = Q.front();
Q.pop();
next.step = curr.step + 1;
for (int i = 0; i < 4; i++)
{
next.x = curr.x + dir[i][0];
next.y = curr.y + dir[i][1];
if(next.x >= 0 && next.x < n && next.y >= 0 && next.y < m && !vis[next.x][next.y] && map[next.x][next.y] != '#')
{
vis[next.x][next.y] = 1;
step[next.x][next.y][f] = next.step;
Q.push(next);
}
}
}
return ;
}
int main()
{
while(cin>>n>>m)
{
getchar();
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
step[i][j][0] = step[i][j][1] = inf;
for (int i = 0; i < n; i++)
scanf("%s",map[i]);
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
if(map[i][j] == 'Y')
{
memset(vis,0,sizeof(vis));
f = 0;
vis[i][j] = 1;
bfs(i,j);
}
else
if(map[i][j] == 'M')
{
memset(vis,0,sizeof(vis));
f = 1;
vis[i][j] = 1;
bfs(i,j);
}
ans = inf;
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
if(map[i][j] == '@')
ans = min(ans,step[i][j][0] + step[i][j][1]);
printf("%d\n",ans*11);
}
return 0;
}