A. 小 A 的点面论
考的是一个小数学知识,
向量的叉乘,即求同时垂直两个向量的向量,即c垂直于a,同时c垂直于b(a与c的夹角为90°,b与c的夹角为90°) c = a×b = (a.y*b.z-b.y*a.z , b.x*a.z-a.x*b.z , a.x*b.y-b.x*a.y)
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
struct Node
{
int x , y , z;
}a , b;
void solve()
{
cin>>a.x>>a.y>>a.z;
cin>>b.x>>b.y>>b.z;
cout<<(a.y*b.z - b.y*a.z)<<" "<<b.x*a.z-a.x*b.z<<" "<<a.x*b.y-b.x*a.y<<endl;
}
int main()
{
solve();
return 0;
}
但由于题目的范围每一个维度的大小都在[-200,200] 之间,所以完全可以暴力跑出来(当时队友脑子糊涂把return 写成 break wa了好几次)。
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
int a1 , b1 , c1;
int a2 , b2 , c2;
void get()
{
for(int i=-200;i<=200;i++)
for(int j=-200;j<=200;j++)
for(int k=-200;k<=200;k++)
{
if(i==0 && j==0 && k==0) continue;
if(a1*i+b1*j+c1*k == 0 && a2*i+b2*j+c2*k == 0)
{
cout<<i<<" "<<j<<" "<<k;
return;
}
}
}
void solve()
{
cin>>a1>>b1>>c1;
cin>>a2>>b2>>c2;
get();
}
int main()
{
solve();
return 0;
}
B. 小 A 的卡牌游戏
应该是dp题待补
C. 小 A 的期末考试
模拟即可,有两个要注意的点
1.平均数要用double,
2.如果分数小于2不是不减,而是减到0
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
struct Node
{
int id , val;
}arr[N];
int n , m;
double sum;
bool cmp(Node x , Node y)
{
if(x.id < y.id) return true;
else return false;
}
void solve()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
int a , b;
scanf("%d%d",&a,&b);
arr[i] = {a,b};
sum += (double)b;
}
sum /= (double)n;
sort(arr+1,arr+n+1,cmp);
for(int i=1;i<=n;i++)
{
if(arr[i].id != m)
{
if(sum <= (double)arr[i].val) arr[i].val -= 2;
if(arr[i].val < 0) arr[i].val = 0;
}
else
{
if(arr[i].val < 60) arr[i].val = 60;
}
}
for(int i=1;i<=n;i++)
{
printf("%d ",arr[i].val);
}
}
int main()
{
solve();
return 0;
}
G. 鸡哥的雕像
有两种方法第一种用乘法逆元但有几种情况
(1)当只有一个数等于mod时,除了该数外都是0
(2)当有两个数以上等于mod时,全时0
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 200020;
const int mod = 998244353;
LL val[N];
int n , m;
int quick_power(int x , int y)
{
int res = 1;
while(y)
{
if(y&1) res = (LL)res*x%mod;
y >>= 1;
x = (LL)x*x%mod;
}
return res%mod;
}
void solve()
{
scanf("%d",&n);
int cnt = 0;
LL temp = 1;
for(int i=1;i<=n;i++)
{
scanf("%lld",val+i);
if(val[i] == mod)
{
cnt++;
}
else temp = temp*val[i]%mod;
}
if(n == 1)
{
printf("%d\n",0);
return;
}
if(cnt == 1)
{
for(int i=1;i<=n;i++)
if(val[i] == mod) printf("%lld ",temp) ;
else printf("%d ",0);
return;
}
else if(cnt >= 2)
{
for(int i=1;i<=n;i++) printf("%d ",0);
return;
}
for(int i=1;i<=n;i++)
{
printf("%lld ",temp*(quick_power(val[i],mod-2)%mod)%mod);
}
}
int main()
{
solve();
return 0;
}
第二种是前缀后缀乘法
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int mod = 998244353;
const int N = 100010;
LL val[N] , lef[N] , rig[N];
int n , m;
void solve()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%lld",val+i);
lef[0] = 1;
rig[n+1] = 1;
for(int i=1;i<=n;i++) lef[i] = lef[i-1]*val[i]%mod;
for(int i=n;i>0;i--) rig[i] = rig[i+1]*val[i]%mod;
if(n == 1)
{
printf("%d ",0);
return;
}
for(int i=1;i<=n;i++)
{
printf("%lld ",lef[i-1]*rig[i+1]%mod);
}
}
int main()
{
solve();
return 0;
}