A:Pump
题目意思: 就是有一个河塘,然后河塘有n个水泵,每个水泵的ai表示 只用这个水泵,ai个小时可以放满(正的时候)或者可以放完(负的时候),1/ai 就是每个小时可以放的水。
我的方法:
输入后,取 1/ai 保存在double定义数组 s[]中 ,所有 1/ai 加起来 求出和sum,判断sum>1e-6(写成0的话会错,精度问题),成立的话,求出 1/sum 向上取整,输出。
不成立的话,对s[]数组从小到大排序,sum不断减去s[i] 直到sum>1e-6(还是精度问题)
如果 i 等于 n都是负数的情况 输出Impossible,
否则 输出 NO i
特别注意1e-6 的精度问题
B:Conflicting Lists
题目意思:取前面尽量少的个数 k ,使上下2个数组的前k个可以对应(就是上面的数组出现过什么,下面的数组也要出现过什么,比如 上面出现1 2 3 下面出现2 3 1,那么前面1个不对应,2个也不对应,3个对应)
解法:看样例
3 5 7 1 2 4 6 8 9 10 数组1
1 2 3 4 7 5 6 8 9 10 数组 2
在数组2中由前往后找到数组1的第一个元素3 ,找到第三个位置,把前面的1 2 标记好,
s1数组再往后是5,5没有标记过,再在数组2中从3的后面一个往后面找,找到第6个位置,找过的数都标记下来,
s1数组再往后是7,已经标记过,然后1,标记过,2标记过,4标记过,这时数组1也找到了第6个位置,跳出循环
输出 6 就是题目要求的答案
for(i=0,j=0;i<n;i++)
{
if(f[s[i]]==0)
{
for(j=x+1;j<n;j++)//x开始是-1
{
f[d[j]]=1;
if(s[i]==d[j]) break;
}
x=j;
}
if(i==x||x==n-1) break;
}//s[]和d[]是输入的2个数组,f[]是标记数组,x用来标记数组d找到什么位置。
C:0/1 Tiles
其实是一个斐波那契数列,%15746就可以了,
1 1
2 00 11
3 100 001 111
4 0000 1100 1001 0011 1111
第四组其实就是第二组后面加00,第三组后面加1,后面类推。
D:Please your Friends
题目意思:自己有1到n的礼物,每行是每个人喜欢的礼物编号,判断是否可以让每个人都拿到自己喜欢的礼物。
用字符串输入,一个一个取出里面的数定义这样一个结构体来保存
struct In
{
int num[100],len;
};
然后 用深搜
int bj[100],biaoji,n;//一个标记数组,一个标记,人的个数(行数)n
void ss(int i)
{
int j;
if(i==n) biaoji=1;//结束的条件
if(biaoji==1) return ;
for(j=0;j<s[i].len;j++)//一个个遍历
{
if(bj[s[i].num[j]]==0)//这个礼物还没有送出去
{
bj[s[i].num[j]]=1;//送出去
ss(i+1);//送下一个人,
bj[s[i].num[j]]=0;//到这里说明不应送出去,回溯
}
}
}
E:Pair Isograms
判断出现的字符是不是2个
F:Candy Store
点 s[0]到s[1]到s[2]...的过程中距理 商店的 最小距离,就是点到线段的距离,用向量可解
1个点的时候要特殊判断。
假设 A点B点的过程中离C点最短的距离
cos(a)=(AB*AC)/(|AB|*|AC|) AB,AC,都是向量 a是AB和AC的夹角
如果cos(a)的值是负的,那么角CAB是钝角,那么点到线段的距离就是AC的长度。
正的时候,设过C垂直AB的点为H,那么 AH/AC=cos(a) ,那么|AH|=cos(a)*|AC|=(AB*AC)/|AB|
那么如果|AH|>|AB| ,C到线段AB的最短距离是|BC|,反之CH就是最短距离
|CH|=sqrt(|AC|*|AC|-|AH|*|AH|)---------勾股定理
循环所有路径 找到最短的距离,输出即可。
G:Numbers
题目意思就是0到N,出现的0的个数
我是 直接暴力 ,
int sum=1;
for(i=1;i<=a;i++)
{
j=i;
while(j!=0)
{
if(j%10==0) sum++;
j=j/10;
}
}
然后 一千万 时间会爆(输出慢一拍),但是一百万能过(运行后秒出)然后输入1234567,再输入2234567,再输入3234567,可以发现后面6位的时候第一位差1然后0的个数相差60万个,换了几个数都有这个规律,所以
一千万的时候直接输出5888897(暴力输出的那个数据)9999999(7个9)的时候 只要暴力到1999999,然后得到的结果加上60万*8就好了,对于大于一百万的数都这样处理,小于一百万的都直接暴力。
H:Root of String
if(strncmp(s,s+j,i)!=0) break;
直接使用了这个函数 s是输入的字符串,i是几个,从1开始加到n,在n%i==0 的情况下 才去判断i是不是可以做为最小的root。
j开始是i,每次加i;如果j加到了n 那么 跳出循环 输出字符串的前i个字符
ps:英语真心重要,能看懂题目才是做题目的前提。