/*
第一题:简单题 http://ac.jobdu.com/problem.php?pid=1465
求解两数是否互质,二重循环,辗转相除法判断即可。
复杂度:O(n^2)
代码:
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <queue>
#include <algorithm>
using namespace std;
#define N 10010
int f[N];
int check(int a,int b){
//辗转相除法、计算最大公约数 为1时表示两者互质、否则不互质,即指两者存在共同约数。
if(a<b) swap(a,b);
while(a>1 && b>1){
if(a%b==0) return 1;
else{
int t = b;
b = a%b;
a = t;
}
}
return 0;
}
int main() {
freopen("/Users/a1/Public/20150717/20150717/in.txt","r",stdin);
int n;
while(scanf("%d",&n) && n){
for(int i=0;i<n;i++) scanf("%d",&f[i]);
int num=0;
for(int i=0;i<n;i++){
for(int j=0;j<n && j!=i;j++){
if(!check(f[i],f[j])) num++;
}
}
printf("%d\n",num);
}
return 0;
}
*/
/*
第二题:最大上升子序列的进化版、求最大生生子序列和,一样,简单DP
http://ac.jobdu.com/problem.php?pid=1480
dp时将长度的累加与判断,转换成和的累加与判断即可。
复杂度:O(n^2)
求和最大可能为1000*10000 = 10^7 在int范围内
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <queue>
#include <algorithm>
using namespace std;
#define N 10010
int f[N];
int num[N];
int main() {
freopen("/Users/a1/Public/20150717/20150717/in.txt","r",stdin);
int n;
while(scanf("%d",&n)!=EOF){
for(int i=0;i<n;i++) scanf("%d",&f[i]);
memset(num,0,sizeof(num));
num[0] = f[0];
for(int i=1;i<n;i++){
num[i] = f[i]; //这句一定记得要写! 否则10、7、8这种情况会错,具体手算一遍即知
for(int j=i-1;j>=0;j--){
if(f[i]>f[j] && f[i] + num[j] > num[i]){ //如果当前值大于j位的数字,并且和大于当前计算得到的num[i]
num[i] = f[i] + num[j];
}
}
}
int maxc = -1;
for(int i=0;i<n;i++)
if(num[i]>maxc) maxc = num[i];
printf("%d\n",maxc);
}
return 0;
}
*/
/*
第三题:树结构判断 http://ac.jobdu.com/problem.php?pid=1481
核心:题意 + 并查集的判断(判断是否只有一棵树)
提示: 一直以为空树不是树! 因此WA了好多发
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <queue>
#include <algorithm>
using namespace std;
#define N 10010
int nodes[N];
int father[N];
int vis[N];
void init(){
memset(nodes,0,sizeof(nodes));
memset(father,0,sizeof(father));
memset(vis,0,sizeof(vis));
for(int i=0;i<N;i++){
father[i] = i;
}
}
int find(int x){
return x==father[x] ? x : find(father[x]);
}
int num1,num2;
void union_nodes(int x,int y){
int fx = find(x);
int fy = find(y);
if(fx!=fy){
father[fx] = fy;
}
else{ //属于同一集合的时候 意味着有错误
num1++; //记录合并了多少次
}
}
int k=1;
int main() {
freopen("/Users/a1/Public/20150717/20150717/in.txt","r",stdin);
int a,b;
while(scanf("%d %d",&a,&b) && a>=0 && b>=0){
init();
int edge = 0;
int flag = 0;
num1 = 0;
while(1){
if(a==0 || b==0) break;
if(find(b)==b && find(a)!=b) //注意这里是有顺序的! 后者向前者合并
father[b] = a;
else flag=1;
vis[a]=1;vis[b]=1;
edge++;
scanf("%d %d",&a,&b);
}
//并查集判断,之前NUM记录了全部的合并次数 本来
int num=0;
for(int i=0;i<N;i++){
if(vis[i]) num++;
}
if(num!=0 && num!=edge+1) flag=1;
printf("Case %d ",k++);
if(flag){
printf("is not a tree.\n");
}else
printf("is a tree.\n");
}
return 0;
}
*/
/*
第四题:谁是你的潜在朋友 http://ac.jobdu.com/problem.php?pid=1156
水题
核心: 记录每本书的入度,每多一个人喜欢,入度+1, 判断每个人的时候,看其最喜欢数目的入度为多少,-1即为其朋友数。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <queue>
#include <algorithm>
using namespace std;
#define N 10010
int f[N];
int in[N];
int main() {
//freopen("/Users/a1/Public/20150717/20150717/in.txt","r",stdin);
int n,m;
while(scanf("%d %d",&n,&m)!=EOF){
memset(in,0,sizeof(in));
for(int i=0;i<n;i++){
scanf("%d",&f[i]);
in[f[i]]++;
}
for(int i=0;i<n;i++){
if(in[f[i]]-1==0) printf("BeiJu\n");
else printf("%d\n",in[f[i]]-1);
}
}
return 0;
}
*/
/*
第五题:买房子 http://ac.jobdu.com/problem.php?pid=1158
简单题
数学题: 求解一次函数与指数在正半轴是否存在交点、(year<=20) 存在输入交点横坐标、否则输出Impossible
代码:
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <queue>
#include <algorithm>
using namespace std;
#define N 10010
int main() {
//freopen("/Users/a1/Public/20150717/20150717/in.txt","r",stdin);
int n,m;
while(scanf("%d %d",&n,&m)!=EOF){
double tot = 200.0;
int year=1;
int flag=1;
while(1){
if(year>20) {flag=0;break;}
tot *= (1.0+(double)m/100);
// printf("tot = %lf num = %lf \n",tot,(year+1)*n - tot );
if((year+1)*n - tot >=0){
flag = year;
break;
}
year++;
}
if(flag) printf("%d\n",flag+1);
else printf("Impossible\n");
}
return 0;
}
*/
/*
第六题:坠落的蚂蚁 http://ac.jobdu.com/problem.php?pid=1159
算是一个思考题,其实把握到本质就好
从样例可以看出,对蚂蚁A最终下落时间有影响的其它蚂蚁,仅为面向蚂蚁A走向的所有蚂蚁。
设:蚂蚁A左侧面向其的蚂蚁数为B,蚂蚁A右侧面向其的蚂蚁数为C
如果B==C,蚂蚁A不会掉下;
否则若B>C,找到蚂蚁A左侧第B-C只蚂蚁D,100-蚂蚁D的位置,即为结果;
若C>B,找到蚂蚁A右侧第C-B只蚂蚁E,蚂蚁E的位置即为结果。
提示:一开始思路想法都没错,但是在找位置时有点差错:
对于数据:
5
20 1
30 -1
40 1
50 0
60 -1
过不了,之前的代码找到位置30的地方,没有判断当前蚂蚁是否向右行走。(在蚂蚁A右侧时要判断是否向左行走)
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <queue>
#include <algorithm>
using namespace std;
#define N 10010
typedef struct LNode{
int location;
int flag;
}LNode;
LNode node[N];
int cmd(LNode x,LNode y){
return x.location < y.location;
}
int main() {
//freopen("/Users/a1/Public/20150717/20150717/in.txt","r",stdin);
int n;
while(scanf("%d",&n)!=EOF){
memset(node,0,sizeof(node));
for(int i=0;i<n;i++) scanf("%d %d",&node[i].location,&node[i].flag);
sort(node,node+n,cmd);
int mid = -1;
for(int i=0;i<n;i++){
if(node[i].flag==0){
mid = i;break;
}
}
int left=0,right=0;
for(int i=mid-1;i>=0;i--){
if(node[i].flag==1) left++;
}
for(int i=mid+1;i<n;i++){
if(node[i].flag==-1) right++;
}
// printf("left = %d right = %d\n",left,right);
if(left==right) printf("Cannot fall!\n");
else{
if(left>right){
int ans;
for(int i=mid-1;i>=0;i--){
if(right==0){
ans = i;break;
}
if(node[i].flag==1){
right--;
}
}
while(node[ans].flag!=1) ans--; //后来加上的代码才过
printf("%d\n",100-node[ans].location);
}else{
int ans;
for(int i=mid+1;i<n;i++){
if(left==0){
ans = i;break;
}
if(node[i].flag==-1) left--;
}
while(node[ans].flag!=-1) ans++; //后来加上的代码才过
printf("%d\n",node[ans].location);
}
}
}
return 0;
}
*/