K:签到,解方程
一开始直接n方暴力,一直wa,可能是数据范围给错了,不清楚。
改成解方程就可以了
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
long long x,y;
while(cin >> x >> y)
{
long long a = (x+y)/2;
long long b = (x-y)/2;
cout << a*b << endl;
}
return 0;
}
F:签到题2,给你一个字符串,求从中选取字母构成avin的概率。
其实就是统计一下a,v,i,n的个数,之后概率相乘即可,分数化简gcd
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n;
while(cin >> n)
{
string s;
cin >> s;
int numa = 0;
int numv = 0;
int numi = 0;
int numn = 0;
for(int i = 0; i < s.length(); i++)
{
if(s[i] == 'a')
{
numa++;
}
if(s[i] == 'v')
{
numv++;
}
if(s[i] == 'i')
{
numi++;
}
if(s[i] == 'n')
{
numn++;
}
}
if(numa*numv*numi*numn == 0)
{
cout << "0/1" << endl;
}
else
{
int fenzi = 1;
int fenmu = n*n*n*n;
fenzi = numa*numv*numi*numn;
int t = __gcd(fenzi,fenmu);
fenzi /= t;
fenmu /= t;
cout << fenzi << "/" << fenmu << endl;
}
}
return 0;
}
G:憨批暴力题
一开始没看懂英语,其实题意是要求b数组的车都等待相同时间。(即b数组所有的车都+t,t相同)
直接枚举1~1000然后判断会不会相撞即可。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <map>
using namespace std;
const int maxn = 1e3 + 50;
int a[maxn],b[maxn];
int n,m;
int c[maxn];
map<int,int> ma;
int judge(int t)
{
for(int i = 1; i <= m; i++)
{
c[i] = b[i] + t;
if(ma[c[i]]) return 0;
}
return 1;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
while(cin >> n >> m)
{
ma.clear();
for(int i = 1; i <= n; i++)
{
cin >> a[i];
ma[a[i]]++;
}
for(int i = 1; i <= m; i++)
{
cin >> b[i];
}
int ans = 0;
for(; ans <= 1001; ans++)
{
if(judge(ans)) break;
}
cout << ans << endl;
}
return 0;
}
D:又是一个暴力题,给你一些条件,求一个数组中满足条件的子序列最长的长度
根据题目中对子序列的要求可以知道:子序列内只有两种数字,交替出现。
首先预处理原数组,记录每个数字出现的所有位置。
那么我们可以在1~c的范围内n方暴力枚举这两个数字。
之后我们就去计算这两个数字i,j能构成最长的子序列即可。
假设先i后j,(因为枚举两个数是n方,所以不用交换位置了)那么我们先取第一个i的位置pos,之后从j中找到第一个位置大于pos的j,位置是pos1,之后再从i里面找到第一个大于pos1的i位置为pos2。以此类推可以得到最长子序列的长度。
n方取最大值即可。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
const int maxn = 1e5 + 50;
vector<int> pos[105];
int n,c;
int solve(int i, int j)
{
if(pos[i].empty() || pos[j].empty()) return 0;
int res = 0;
int posi = 0;
int t = 0;
int lastj = 0;
for(t = 0; t < pos[j].size(); t++)
{
if(posi >= pos[i].size()) break;
if(pos[j][t] > pos[i][posi])
{
res += 2;
// if(i == 1 && j == 2)
// cout << pos[i][posi] << " " << pos[j][t] << endl;
lastj = pos[j][t];
while(pos[i][posi] < pos[j][t] && posi < pos[i].size())
{
posi++;
}
}
else
{
continue;
}
}
int numa = pos[i].size() - 1;
//cout << i << " " << numa << endl;
int lasti = pos[i][numa];
if(lasti > lastj) res++;
return res;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
while(cin >> n >> c)
{
for(int i = 1; i <= c; i++)
{
pos[i].clear();
}
for(int i = 1; i <= n; i++)
{
int a;
cin >> a;
pos[a].push_back(i);
}
int ans = 0;
for(int i = 1; i <= c; i++)
{
for(int j = 1; j <= c; j++)
{
if(i != j)
{
ans = max(ans,solve(i,j));
}
}
}
cout << ans << endl;
}
return 0;
}
注意:如果vector的长度为0,不可以调用size(),会终止导致程序无输出,需要特判vector为空的情况。
——————————————————————————————————————————————————
队友写的I,J,自己补上
I:求n个小数,在小数点后第三位四舍五入,误差的总和。
用字符串存小数,在小数点后取三位,计算四舍五入即可。
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int n;
while(cin >> n)
{
double ans = 0;
for(int i = 1; i <= n; i++)
{
string s;
cin >> s;
long long a = 0;
for(int i = 0; i < s.length(); i++)
{
if(s[i] == '.')
{
a = (s[i+1]-'0')*100 + (s[i+2]-'0')*10 + (s[i+3]-'0');
}
}
//得到小数点后三位
long long b = a;
if(a % 10 >= 5)
{
b = a;
b -= (a % 10);
b += 10;
}
else
b -= (b % 10);
double sum = b - a;
// cout << a << " " << b << endl;
ans += sum / 1000.0;
}
printf("%.3lf\n",ans);
}
return 0;
}
J:求数组的最小公倍数,之后分配数目构成最小公倍数的倍数即可。
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn = 1e3 + 50;
long long a[maxn];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
long long n,m;
while(cin >> n >> m)
{
vector<long long> ans;
for(int i = 1; i <= n; i++)
{
cin >> a[i];
}
ans.push_back(0);
long long t = 1;
for(int i = 1; i <= n; i++)
{
t = t / __gcd(t,a[i]) * a[i];
}
long long sum = 0;
for(int i = 1; i <= n; i++)
{
long long num = t / a[i];
sum += num;
ans.push_back(num);
}
if(m % sum != 0)
{
cout << "No" << endl;
}
else
{
cout << "Yes" << endl;
int p = m / sum;
for(int i = 1; i <= n; i++)
{
if(i != n)
cout << ans[i]*p << " ";
else cout << ans[i]*p << endl;
}
}
}
return 0;
}
——————————————————————————————————————————————————
H:给你一个区间1~n,从中选取两个区间,求两区间相交的概率
RNG NB!
假设我选择的两个区间:[a1,b1]与[a2,b2]。
那么两个区间不相交的情况为:b1 < a2 或者 b2 < a1,满足其中一个,即可不相交。
得到: min(b1,b2) < max(a1,a2)即可。
那么我们去选择 min(b1,b2) 与 max(a1,a2),简称b和a。
总共有nn种选择,其中b<a,有(n-1) n / 2种
那么得到:不相交的概率 = 1 - 相交 = 1 - (n-1)* n / 2 / (n*n) = (n+1)/(2n)。
快速幂取模,费马小定理
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int mod = 1e9 + 7;
long long quickPower(long long x, long long y)//快速幂加取模
{
long long result = 1; // 定义答案
while (y > 0) // 当指数大于 0 时进行幂运算
{
if (y & 1) // y 和 1 做与运算,相当于对 2 求模
{
result = (result * x) % mod;// 如果 y 为奇数,则结果只乘一个 x
}
x = x * x % mod; // x 乘二次方,下次使用
y = y >> 1; // y 右移一位,相当于除以 2
}
return result % mod; // 返回结果
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
long long n;
while(cin >> n)
{
long long ans = quickPower((2*n),mod-2);
ans *= (n+1);
ans %= mod;
cout << ans << endl;
}
return 0;
}
B:概率dp
dp[i]表示从i走到i+1的期望消耗
在i走到i+1时,分情况讨论:
- 没有丢: 1-p
- 丢了,并且走到n才发现: p * 2 * (1-q)^(n-i) * (n-i) 一直没有发现,走到n,再回到i
- 丢了,没走到n就发现了:需要枚举i后x步发现丢失了。 2 * p * q * (1-q)^x * x, x从0枚举到n-i-1
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn = 1e5 + 50;
double dp[maxn];
//表示从i走到i+1时的期望
double sum[maxn];
double q1[maxn];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
long long l;
double p,q;
while(cin >> l >> p >> q)
{
sum[0] = 0;
q1[0] = 1;
for(int i = 1; i <= l; i++)
{
q1[i] = q1[i-1] * (1-q);
sum[i] = sum[i-1] + q1[i]*i;
}
double ans = 0;
for(int i = 0; i < l; i++)
{
ans += (1 - p + 2*p*q1[l-i]*(l-i) + 2*p*q*(sum[l-i-1])) / (1-p);
}
printf("%.6lf\n",ans);
}
return 0;
}