湖南大学ACM程序设计新生杯大赛(同步赛)(重现赛)
B.Build
ps:待补
Build题解
C.Do you like banana? 计算几何
题意:判断线段是否相交
思路:向量叉乘
线段相交判定知识点参考
ac代码:
#include<iostream>
#include<cstdio>
#define ZERO 1e-9
using namespace std;
struct point{
double x,y;
};
double vector_mul(point A,point B)//向量乘法
{
return (A.x*B.y-B.x*A.y);
}
void negative(point &A,point &B)
{
A.x=-B.x,A.y=-B.y;//取反
}
bool is_intersect(point A,point B,point C,point D)
{
//计算叉乘((AC*AD)*(BC*BD))和叉乘((DA*DB)*(CA*CB)),若二者皆非正则相交,否则不相交
point AC,AD,DA,DB,BC,BD,CA,CB;
AC.x=C.x-A.x,AC.y=C.y-A.y;
AD.x=D.x-A.x,AD.y=D.y-A.y;
DB.x=B.x-D.x,DB.y=B.y-D.y;
BC.x=C.x-B.x,BC.y=C.y-B.y;
negative(DA,AD);
negative(BD, DB);
negative(CB, BC);
negative(CA,AC);
double res1=vector_mul(AC,AD);
double res2=vector_mul(BC,BD);
double res3=vector_mul(DA,DB);
double res4=vector_mul(CA,CB);
if(res1*res2<=ZERO&&res3*res4<=ZERO)return true;
return false;
}
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int t;
cin>>t;
while(t--){
point A,B,C,D;
cin>>A.x>>A.y>>B.x>>B.y>>C.x>>C.y>>D.x>>D.y;
if(is_intersect(A,B,C,D))cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
return 0;
}
D.number 暴力打表+去重
分析:n的范围是5*1e7,因为要取2次方+3次方+4次方的和在n范围内,取个1e4就已经足够了,没必要取到1e7,况且取到1e7还容易爆,打好1e4范围内的一个质数表以后for循环暴力判断条件就行,要注意的一个点是要记得去重,因为有的不同次方组合的和是一样的,只能归成一种,用vis数组标记去重即可
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e4;
int primes[N],cnt,p2[N],p3[N],p4[N];
bool vis[50000000+3];
void get_primes(int n)
{
for(int i=2;i<=n;i++){
if(!vis[i])primes[cnt++]=i;
for(int j=0;primes[j]<=n/i;j++){
vis[i*primes[j]]=true;
if(i%primes[j]==0)break;
}
}
}
int main()
{
int n;
cin>>n;
get_primes(1e4);
int ans=0;
memset(vis,false,sizeof(vis));
for(int i=0;i<cnt;i++){
if(primes[i]*primes[i]>n)break;
for(int j=0;j<cnt;j++){
if(primes[j]*primes[j]*primes[j]>n)break;
for(int k=0;k<cnt;k++){
int t=primes[i]*primes[i]+primes[j]*primes[j]*primes[j]+primes[k]*primes[k]*primes[k]*primes[k];
if(t>n)break;
if(vis[t])continue;
vis[t]=true;ans++;
}
}
}
cout<<ans<<endl;
return 0;
}
ps:郁闷,没有去重一直不通过,而且老是怀疑这题暴力真能过吗,然后。。。一直没过。。因为没有计算好所需范围以及没有加上一些语句用来跳过一些不必要的判断加快程序运行,再加上没有考虑去重,都导致我这题没能ac,吸取教训
E.Permutation 规律
思路:
#include<iostream>
using namespace std;
int main()
{
int n;
cin>>n;
if(n<=2)cout<<"Yes"<<endl;
else cout<<"No"<<endl;
return 0;
}
G.The heap of socks
思路:map容器
#include<iostream>
#include<map>
#include<algorithm>
using namespace std;
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int t;
cin>>t;
while(t--){
int n;
cin>>n;
map<int,int> mp;
for(int i=0;i<n;i++){
int x;
cin>>x;
mp[x]++;
}
int sum=0,i=0;
for(auto it:mp){
while(it.second--){
sum+=it.first;
i++;
if(i==2)break;
}
if(i==2)break;
}
cout<<sum<<endl;
}
return 0;
}
H.Yuanyuan Long and His Ballons 公式题
分析:环染色问题公式直接代上去就行,题目中说要取模,因此计算次方时要用快速幂
公式:ans=(-1)^n*(k-1)+(k-1) ^n
#include<iostream>
using namespace std;
typedef long long ll;
const ll mod=100000007;
ll quick_pow(ll x,ll y,ll mod)
{
ll ans=1;
while(y){
if(y&1)ans=(ans*x)%mod;
x=(x*x)%mod;
y>>=1;
}
return ans%mod;
}
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int t;
cin>>t;
while(t--){
int n,k;
cin>>n>>k;
cout<<quick_pow(-1,n,mod)*(k-1)+quick_pow(k-1,n,mod)<<endl;
}
return 0;
}
ps:补题才晓得这居然直接用公式的,才知道有公式,高中数学没学好,现在还得补以前的坑 _
I.Piglet treasure hunt Series I
ps:待补
题解
J.Piglet treasure hunt Series II
ps:待补
题解
本文地址:https://blog.csdn.net/fusu123456789/article/details/107820108
上一篇: 升级 MySQL