题目地址:http://acm.hdu.edu.cn/diy/contest_show.php?cid=28491
1001
把HDU 4082 稍微改一下就过了
/*
数相似三角形个数
用map记录角度
注意:
1、去除重点
2、排除共线的情况
3、精度问题。
WA了8次了
*/
#include<stdio.h>
#include<math.h>
#include<map>
#include<iostream>
#include<string.h>
using namespace std;
const double eps=1e-6;
map<long long,int>mp;
struct Node
{
int x,y;
}node[50];
double dis(Node a,Node b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
void solve(Node a,Node b,Node c)
{
double la=dis(b,c);
double lb=dis(a,c);
double lc=dis(a,b);
if(la+lb<=lc+eps)return;
if(lb+lc<=la+eps)return;
if(la+lc<=lb+eps)return;
double A=acos((lb*lb+lc*lc-la*la)/(2*lb*lc));
double B=acos((la*la+lc*lc-lb*lb)/(2*la*lc));
double C=acos((la*la+lb*lb-lc*lc)/(2*la*lb));
if(A<eps||B<eps||C<eps)return;
int t1=(int)(A*10000);
int t2=(int)(B*10000);
int t3=(int)(C*10000);
if(t1>t2)swap(t1,t2);
if(t1>t3)swap(t1,t3);
if(t2>t3)swap(t2,t3);
if(t1==0)return;
long long t=t1*1000000*1000000+t2*1000000+t3;
mp[t]++;
}
int hole[220][220];
int main ()
{
//freopen("in.txt","r",stdin);
int n;
while(~scanf("%d%d",&node[0].x,&node[0].y))
{
int t=0;
memset(hole,0,sizeof(hole));
for(int i=1;i<6;i++)
{
scanf("%d%d",&node[i].x,&node[i].y);
}
n=t;
mp.clear();
//for(int i=0;i<n;i++)
// for(int j=i+1;j<n;j++)
// for(int k=j+1;k<n;k++)
// solve(node[i],node[j],node[k]);
int i=0;
solve(node[i],node[i+1],node[i+2]);
i=3;
solve(node[i],node[i+1],node[i+2]);
int ans=0;
map<long long,int>::iterator it;
for(it=mp.begin();it!=mp.end();it++)
{
int t=it->second;
if(t>ans)ans=t;
}
//printf("%d\n",ans);
ans--;
if(ans==1) puts("Yes");
else puts("No");
}
return 0;
}
1002 签到题,直接贪心
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<iostream>
#include<algorithm>
#include<sstream>
#include<fstream>
#include<vector>
#include<map>
#include<stack>
#include<list>
#include<set>
#include<queue>
#define LL long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1 | 1
/*
正反循环的宏定义
*/
#define ffr(i,x,y) for(int i=(x),_en=(y);i<=_en;i++)
#define rff(i,x,y) for(int i=(x),_en=(y);i>=_en;i--)
#define clr(f,z) memset(f,z,sizeof(f))
using namespace std;
const int maxn=100005,inf=1<<29;
int dir[][2]={ {0,1},{-1,0},{0,-1},{1,0},{-1,1},{-1,-1},{1,-1},{1,1}};//常用方向数组
int n,m,t;//常用全局变量
int a[maxn],b[maxn],dp[maxn],num[maxn],vis[maxn];//常用全局数组
struct node
{
int x,y;
};//常用结构体
vector<int>G[maxn];//常用邻接表
/*
函数重载,可根据参数类型,自动选择输入
*/
bool sf(int &x) { return scanf("%d",&x)==1;}
bool sf(char *x){return scanf("%s",x)==1;}
bool sf(double &x){return scanf("%lf",&x)==1;}
bool sf(LL &x) { return scanf("%I64d",&x)==1;}
void pf(int x,int op) {
op?printf("%d\n",x):printf("%d ",x);//op==0打印数字加空格,op==1打印数字加换行
}
void pf(LL x,int op) {
op?printf("%I64d\n",x):printf("%I64d ",x);//op==0打印数字加空格,op==1打印数字加换行
}
int get_rand(int n)
{
return (int)((double)rand() / RAND_MAX * n) ;
}
int v[]={20,10,5,1};
int main()
{
// freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
//srand(time(NULL));
while(sf(n))
{
int ans=0,p=0;
for(int i=0;i<4;i++)
{
ans+=n/v[i];
n%=v[i];
}
pf(ans,1);
}
return 0;
}
1003 暴力枚举全排列
#include<iostream>
#include<cstdio>
using namespace std;
const int inf=1e9;
int n,m,ans[15];
int a[15];//待排列的数存储在此
bool vis[15];
int a1[15],a2[15],b1[15],b2[15];
int res;
int Count1()
{
int s=0;
for(int i=0;i<m;i++)
if(b2[i]-a1[ans[i]]>0) s+=b1[i];
return s;
}
int Count2()
{
int s=0;
for(int i=0;i<m;i++) s+=b1[i];
for(int i=0;i<n;i++)
{
s-=b1[ans[i]];
if(b2[ans[i]]-a1[i]>0) s+=b1[ans[i]];
}
return s;
}
void dfs1(int d,int cnt)//按字典序输出n个数选m个数的所有排列
{
if(cnt==m)
{
res=min(res,Count1());
return ;
}
for(int i=0;i<n;i++)
{
if(!vis[i])
{
ans[cnt]=a[i];
vis[i]=1;
dfs1(i+1,cnt+1);
vis[i]=0;
}
}
}
void dfs2(int d,int cnt)//按字典序输出n个数选m个数的所有排列
{
if(cnt==n)
{
//cout<<n<<endl;
// for(int i=0;i<n;i++) cout<<ans[i]<<" ";cout<<endl;
res=min(res,Count2());
return ;
}
for(int i=0;i<m;i++)
{
if(!vis[i])
{
ans[cnt]=a[i];
vis[i]=1;
dfs2(i+1,cnt+1);
vis[i]=0;
}
}
}
int main()
{
// freopen("in.txt","r",stdin);
int t;
cin>>t;
while(t--)
{
cin>>n>>m;
for(int i=0;i<n;i++) cin>>a1[i]>>a2[i];
for(int i=0;i<m;i++) cin>>b1[i]>>b2[i];
fill(vis,vis+15,0);
for(int i=0;i<15;i++) a[i]=i;
res=inf;
if(n>=m) dfs1(0,0);
else dfs2(0,0);
cout<<res<<endl;
}
return 0;
}
1004 简单DP
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<iostream>
#include<algorithm>
#include<sstream>
#include<fstream>
#include<vector>
#include<map>
#include<stack>
#include<list>
#include<set>
#include<queue>
#define LL long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1 | 1
/*
正反循环的宏定义
*/
#define ffr(i,x,y) for(int i=(x),_en=(y);i<=_en;i++)
#define rff(i,x,y) for(int i=(x),_en=(y);i>=_en;i--)
#define clr(f,z) memset(f,z,sizeof(f))
using namespace std;
const int maxn=1000005,inf=1<<29;
int dir[][2]={ {0,1},{-1,0},{0,-1},{1,0},{-1,1},{-1,-1},{1,-1},{1,1}};//常用方向数组
int n,m,t;//常用全局变量
int a[maxn],b[maxn],dp[maxn],num[maxn],vis[maxn];//常用全局数组
struct node
{
int x,y;
};//常用结构体
vector<int>G[maxn];//常用邻接表
/*
函数重载,可根据参数类型,自动选择输入
*/
bool sf(int &x) { return scanf("%d",&x)==1;}
bool sf(char *x){return scanf("%s",x)==1;}
bool sf(double &x){return scanf("%lf",&x)==1;}
bool sf(LL &x) { return scanf("%I64d",&x)==1;}
void pf(int x,int op) {
op?printf("%d\n",x):printf("%d ",x);//op==0打印数字加空格,op==1打印数字加换行
}
void pf(LL x,int op) {
op?printf("%I64d\n",x):printf("%I64d ",x);//op==0打印数字加空格,op==1打印数字加换行
}
int get_rand(int n)
{
return (int)((double)rand() / RAND_MAX * n) ;
}
int v[]={20,10,5,4,1};
int main()
{
// freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
//srand(time(NULL));
//while(sf(n))
fill(dp,dp+maxn,inf);
dp[0]=0;
ffr(i,1,maxn-1) ffr(j,0,5) if(i>=v[j]) dp[i]=min(dp[i],dp[i-v[j]]+1);
while(sf(n)) pf(dp[n],1);
return 0;
}
1005
和HDU 1556很相似
不过用线段树或树状数组会TLE
用神奇的模拟过掉了,复杂度O(n+m)
#include<cstdio>
#include<cstring>
#include<iostream>
#define LL long long
using namespace std;
const int maxn=1000005;
LL aa[maxn],b[maxn],c[maxn];
int main()
{
//freopen("in.txt","r",stdin);
int n,m;
while(~scanf("%d%d",&n,&m))
{
memset(c,0,sizeof(c));
for(int i=1;i<=n;i++) scanf("%I64d",&aa[i]);
for(int i=1;i<=m;i++)
{
int a,b,x;
scanf("%d%d%d",&a,&b,&x);
if(a>b) swap(a,b);
if(a==0) a++;
if(b==0) continue;
c[a]+=x,c[b+1]-=x;
}
LL s=0;
for(int i=1;i<n;i++)
{
s+=c[i];
printf("%I64d ",s+aa[i]);
}
printf("%I64d\n",s+c[n]+aa[n]);
}
return 0;
}
1006 和POJ3090很像,具体做法自行百度
先预处理出欧拉函数,再算出欧拉函数的前缀和
这里要注意用long long和n=0时的特判
/*
*
*因为是关于对角线对称,所以只需要求解矩形的下半部分在乘以2就可以了
*满足题意的点对的要求是x和y互质,可以使用欧拉函数
*需要注意的是特殊的点对(1,1)(0,1)(1,0)
*这三个需要单独拿出来计算
*/
#include <iostream>
using namespace std;
long long ans[100010];
long long eular(int n)
{
long long ret=1;
for(int i=2;i*i<=n;i++)
{
if(n%i==0)
{
ret*=(i-1);
n/=i;
while(n%i==0)
{
n/=i;
ret*=i;
}
}
}
if(n>1)
ret*=n-1;
return ret;
}
void set()
{
for(int i=2;i<100002;i++)
ans[i]=eular(i);
}
int main()
{
int t;
//cin>>t;
set();
int aim;
while(cin>>aim)
{
long long sum=0;
for(int i=2;i<=aim;i++)
sum+=ans[i];
// cout<<j<<" "<<aim<<" "<<sum*2+3<<endl;
if(aim==0) cout<<0<<endl;
else cout<<sum*2+1<<endl;
}
}
1007 暴力枚举C的约数即可,注意特判C=0时的情况
#include<cstdio>
#include<iostream>
using namespace std;
int main()
{
// freopen("in.txt","r",stdin);
int b,c;
while(~scanf("%d%d",&b,&c))
{
if(c==0)
{
printf("%d %d\n",0,b);
continue;
}
int p,q,f=0;
if(c>0)
{
for(int i=1;i<=c;i++)
{
if(c%i==0)
{
if(c/i+i==b)
{
p=c/i;
q=i;
f=1;
break;
}
if(-c/i-i==b)
{
p=-c/i;
q=-i;
f=1;
break;
}
}
}
}
else
{
c=-c;
for(int i=1;i<=c;i++)
{
if(c%i==0)
{
if(c/i-i==b)
{
p=c/i;
q=-i;
f=1;
break;
}
if(-c/i+i==b)
{
p=-c/i;
q=i;
f=1;
break;
}
}
}
}
if(p>q) swap(p,q);
if(f) printf("%d %d\n",p,q);
else puts("impossible");
}
return 0;
}
1008、1009表示做不来。