首先对二级算法做一个总结吧,大体上都是一些不是很难的题,但是很有助于提高的,毕竟对于我这样的萌新来说。既然题已经刷完了,当然还是写一篇总结,对学到的经验进行一下总结。。。不然下次碰到不会的还是不会就很尴尬了。
下面进入正文:
1873 初中的算术:
就是大数运算,如果想写的同学可以用C++去写写,也不是很难就是麻烦点,就当是练手了,这方面的博客很多直接百度就好了。这里笔者比较懒就直接用Java暴力过了。。。Java大法好啊。
import java.math.BigDecimal;
import java.util.*;
public class MAIN {
public static void main(String args[])
{
Scanner cin = new Scanner(System.in);
double m = cin.nextDouble();
int n = cin.nextInt();
BigDecimal ans=new BigDecimal("1");
for(int i = 0; i < n; i++)
ans = ans.multiply(BigDecimal.valueOf(m));
String s=ans.stripTrailingZeros().toPlainString();
int i=0;
if(s.charAt(0)=='0'&&s.charAt(1)=='.')
i=1;
for(;i<s.length();i++)
System.out.print(s.charAt(i));
}
}
二进制的重要性,存0-1e6的这些指数的出现次数,然后不停的除2进位就可以,从低位开始,只要是留下的某一位进不上去剩下一个了,那就是一定要花费一次机会去运送这个。需要注意的是:1,题中输入的货物的2^wi的wi不是货物的重量;2,数组最大要开大点,后面可能会进好几次超过1e6.
#include<iostream>
#include<cstring>
#include<math.h>
#include<stdlib.h>
#include<cstring>
#include<cstdio>
#include<utility>
#include<algorithm>
#include<map>
using namespace std;
typedef long long ll;
const int Max = 1000024;
const int mod = 1e9+7;
const int Hash = 10000;
const int INF = 1<<30;
int n;
ll arr[Max];
int main( )
{
//freopen("input.txt", "r", stdin);
while(~scanf("%d", &n))
{
memset(arr, 0, sizeof(arr));
for(int i=0; i<n; i++)
{
int t;
scanf("%d", &t);
arr[t]++;
}
int ans = 0;
for(int i=0; i<Max; i++)
{
arr[i+1] += arr[i]/2;
arr[i] %= 2;
if(arr[i] == 1)
ans++;
}
cout<<ans<<endl;
}
return 0;
}
核心就是每次失去一个可用位置k,对于整个区间的影响。也就是只需要计算出来k位于的区间[l, r]本来的可容纳战舰数再减去k被占据之后,可容纳的战舰数。有点像莫对算法里的区间转移的问题。解决了这个就按题意模拟就行了
#include<iostream>
#include<cstring>
#include<math.h>
#include<stdlib.h>
#include<cstring>
#include<cstdio>
#include<utility>
#include<algorithm>
#include<map>
using namespace std;
typedef long long ll;
const int Max = 1e6+5;
const int mod = 1e9+7;
const int Hash = 10000;
const int INF = 1<<30;
int n, k, a;
ll arr[Max];
int main( )
{
//freopen("input.txt", "r", stdin);
while(~scanf("%d%d%d", &n,&k,&a))
{
memset(arr, 0, sizeof(arr));
int m;
scanf("%d", &m);
int ans = 0;
int MaxNum = (n+1)/(a+1);
for(int i=1; i<=m; i++)
{
int t, prenum, curnum;//分区间之前能容纳的战舰数,分区间之后能容纳的战舰数
scanf("%d", &t);
if(ans)
continue;
arr[t] = 1;
int left=t-1, right=t+1;
while(left>=1 && arr[left]==0)
left--;
while(right<=n && arr[right]==0)
right++;
prenum = (right-left)/(a+1);
curnum = (t-left)/(a+1)+(right-t)/(a+1);
MaxNum -= prenum - curnum;
if(MaxNum<k && ans==0)
ans = i;
}
if(ans)
cout<<ans<<endl;
else
cout<<-1<<endl;
}
return 0;
}
1489 蜥蜴和地下室:
dfs,这个没啥好说的,就是多练练吧,数据量很小,dfs就好了
#include<iostream>
#include<cstring>
#include<math.h>
#include<stdlib.h>
#include<