根据“信息学初学者之家”网站的统计,Ural(俄罗斯的Ural州立大学的简称 ,有名的Ural Online Problem Set 就是该校的系统)的题目类型大概呈如下的分布:
**搜索** 动态规划 贪心 构造 图论
**约10%** 约15% 约5% 约5% 约10%
计算几何 纯数学题 数据结构 其它 约5% 约20% 约5% 约25%
搜索算法是利用计算机的高性能来有目的地穷举一个问题的部分或所有的可能情况,从而求出问题的解的一种方法。
搜索过程实际上是根据初始条件和扩展规则构造一棵解答树并寻找符合目标状态的节点的过程。
二分:假设给出若干个(可以很多)有序的整数,请查找某个元素是否存在(注意一定是单调问题!)
时间复杂度:O(logN)
函数:
int BiSearch(int a[],int n,int x)
{
int left=0, right=n-1;
while(left<=right) // 注意=不能少
{
int middle=(left+right)/2; //整数除法
if(a[middle]==x) //找到的情况
return middle;
if(x>a[middle]) //如果比中值大
left=middle+1;
else //如果比中值小
right=middle-1;
}
return -1;
}
hdoj2199
两个注意点:1、对于这种小数题精度开得越小越好,别吝啬
2、最后也不一定能找到,所以直接返回left或者middle的值
#include<iostream>
#include<vector>
#include<map>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<stack>
#include<cstring>
#define inf 0x3f3f3f3f
using namespace std;
const int N = 1000005;
double fun(double x){
double ans = 8*pow(x, 4) + 7*pow(x, 3) + 2*pow(x, 2) + 3*x + 6;
return ans;
}
double bisearch(double left, double right, double y){
while(right-left>1e-10){
double mid = (left+right)/2;
double t = fun(mid);
if(fabs(t-y)<1e-9)
return mid;
else if(y-t>1e-9)
left=mid+(1e-8);
else
right=mid-(1e-8);
}
return left;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
double y;
scanf("%lf",&y);
if(fun(0)>y||fun(100)<y){
printf("No solution!\n");
continue;
}
else
{
double ans = bisearch(0, 100, y);
printf("%.4lf\n",ans);
}
}
return 0;
}
hdoj 2899
#include<iostream>
#include<vector>
#include<map>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<stack>
#include<cstring>
#define inf 0x3f3f3f3f
using namespace std;
const int N = 1000005;
double fun(double x){
double ans = 42*pow(x, 6) + 48*pow(x, 5) + 21*pow(x, 2) + 10*x;
return ans;
}
double fun2(double x,double y){
double ans = 6*pow(x, 7)+8*pow(x,6)+7*pow(x,3)+5*x*x-y*x;
return ans;
}
double bisearch(double left, double right, double y){
while(right>left){
double mid = (left+right)/2;
double t = fun(mid);
if(fabs(t-y)<1e-7)
return mid;
else if(y>t)
left=mid+(1e-7);
else
right=mid-(1e-7);
}
return left;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
double y;
scanf("%lf",&y);
double ans = bisearch(0, 100, y);
printf("%.4lf\n",fun2(ans, y));
}
return 0;
}
hdoj2648
map的使用
#include<iostream>
#include<vector>
#include<map>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<stack>
#include<cstring>
#define inf 0x3f3f3f3f
using namespace std;
const int N = 1005;
map<string, int>shop;
int main(){
int n;
while(scanf("%d",&n)!=EOF){
for(int i=0;i<n;i++){
string s;
cin>>s;
shop[s] = 0;
}
int m;
scanf("%d",&m);
for(int i=0;i<m;i++){
for(int i=0;i<n;i++){
int t;
cin>>t;
string tt;
cin>>tt;
shop[tt]+=t;
}
int ans = 1;
map<string,int>::iterator iter = shop.begin();
while(iter!=shop.end()){
if(iter->second>shop["memory"])
ans+=1;
iter++;
}
printf("%d\n",ans);
}
shop.clear();
}
return 0;
}
hdoj2141
#include<iostream>
#include<vector>
#include<map>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<stack>
#include<cstring>
#define inf 0x3f3f3f3f
using namespace std;
const int N = 505;
const int NN = 1000000;
int d[NN];
int bisearch(int left, int right, int y, int a[]){
while(right>=left){
int mid = (left+right)/2;
if(a[mid]==y)
return mid;
else if(y>a[mid])
left=mid+1;
else
right=mid-1;
}
return -1;
}
int cmp(int a, int b){
return a<b;
}
int main(){
int l, m, n;
int cnt = 1;
while(scanf("%d%d%d",&l,&n,&m)!=EOF){
int a[N], b[N], c[N];
for(int i=0;i<l;i++) scanf("%d",&a[i]);
for(int i=0;i<n;i++) scanf("%d",&b[i]);
for(int i=0;i<m;i++) scanf("%d",&c[i]);
int t = 0;
for(int i=0;i<l;i++)
for(int j=0;j<n;j++)
d[t++] = a[i]+b[j];
sort(c,c+m,cmp);
sort(d,d+t,cmp);
int s;
scanf("%d",&s);
printf("Case %d:\n",cnt++);
while(s--){
int y;
scanf("%d",&y);
int ans;
bool f = false;
for(int i=0;i<m;i++){
int ans = bisearch(0,t-1,y-c[i],d);
if(ans==-1)
continue;
else
f = true;
if(f) break;
}
if(f) printf("YES\n");
else printf("NO\n");
}
}
return 0;
}