A无序数组
a,b最大是1e5 先暴力打表因子数(第一个双循环)
题中要求是无序的 所以要去掉重复的 根据例子我们可以发现 重复的组数是 C(相同因子数,2) 即一个组合数
相同因子数直接求两个数的gcd即可 然后a[gcd]对应的就是相同的因子数
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int N = 1e5 + 5;
const int mod = 1e9 + 7;
int a[N];
int main()
{
for(int i = 1;i <= 100000;i ++)
{
for(int j = 1;i * j <= 100000;j ++)
a[i * j] ++;
}
int T, n, m;
scanf("%d",&T);
while(T --)
{
scanf("%d%d",&n,&m);
int gcd = __gcd(n,m);
printf("%d\n",a[n]*a[m] - a[gcd]*(a[gcd]-1)/2);
}
return 0;
}
B 路径数量
01矩阵,相当于一个点到另一个点的距离为1
b数组的 i表示 到达i地 j表示走j步 那么最终达到的条件就是 b[n][k] 即到达 n点用k步 初始化b[1][0] = 1
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int N = 35;
const int mod = 1e9 + 7;
ll a[N][N], b[N][N];
int n, K;
int main()
{
cin >> n >> K;
for(int i = 1;i <= n;i ++)
{
for(int j = 1;j <= n;j ++)
cin >> a[i][j];
}
b[1][0] = 1;
for(int k = 1;k <=K;k ++)
{
for(int i = 1;i <= n;i ++)
{
for(int j = 1;j <= n;j ++)
{
if(a[i][j])
b[j][k] += b[i][k-1];
}
}
}
cout << b[n][K] << endl;
return 0;
}
话说这种问题是矩阵乘法问题 k长路径数 即求矩阵k次幂然后 a[1][n]即是答案
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<ll> vec;
typedef vector<vec> mat;
mat mul(mat& A, mat& B)
{
mat C(A.size(), vec(B[0].size()));
for (int i = 0; i < A.size(); i++)
for (int k = 0; k < B.size(); k++)
if (A[i][k])
for (int j = 0; j < B[0].size(); j++)
C[i][j] = (C[i][j] + A[i][k] * B[k][j]);
return C;
}
mat Pow(mat A, ll n)
{
mat B(A.size(), vec(A.size()));
for (int i = 0; i < A.size(); i++) B[i][i] = 1;
for (; n; n >>= 1, A = mul(A, A))
if (n & 1) B = mul(B, A);
return B;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("1.in", "r", stdin);
freopen("1.out", "w", stdout);
#endif
int n, k;
scanf("%d%d", &n, &k);
mat G(n, vec(n));
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
scanf("%lld", &G[i][j]);
G = Pow(G, k);
printf("%lld\n", G[0][n - 1]);
return 0;
}
C数列下标
昨天应该是数据出了锅。。 段错误
其实暴力可过
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int N = 1e4 + 5;
const int mod = 1e9 + 7;
ll a[N],b[N];
int main()
{
int n;
scanf("%d",&n);
memset(b,INF,sizeof(b));
for(int i = 1;i <= n;i ++)
scanf("%lld",&a[i]);
for(int i = n;i > 1;i --)
{
for(int j = 1;j < i;j ++)
{
if(a[i] > a[j] && i < b[j])
b[j] = i;
}
}
for(int i = 1;i <= n;i ++)
{
if(i != 1)
printf(" ");
if((int)b[i] == INF)
printf("0");
else
printf("%d",b[i]);
}
return 0;
}
D 烛光晚餐
规律就是 开关n次之后 只有平方数会亮着 即求平方数的个数即可
1.可以暴力打表找规律
2(数学)详细可参考 http://www.cnblogs.com/haolujun/archive/2012/10/10/2719031.html
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int N = 1e4 + 5;
const int mod = 1e9 + 7;
int main()
{
ll n, ans;
cin >> n;
cout << (ll)sqrt(n) << endl;
return 0;
}
E 括号序列
设置两个记录左右括号带匹配数量的变量 l, r 初始为0
然后遍历整个串
如果遇到左括号 ( 那么 l++ 如果遇到右括号 判断当前待匹配左括号是否为0 不为0 就匹配一个 l--
否则的话 待匹配右括号数量+1 即 r++
最后匹配次数即为 带匹配括号的一半
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int N = 5e6 + 5;
const int mod = 1e9 + 7;
char a[N];
int main ()
{
int l, r, n;
scanf("%d",&n);
l = r = 0;
scanf("%s",a);
for(int i = 0;i < n;i ++)
{
if(a[i] == '(')
l ++;
else
{
if(l != 0)
l --;
else
r ++;
}
}
cout << (l + 1) / 2 << endl;
return 0;
}
F 假的数学游戏
比赛的时候没想到啥好方法。。因为给范围了 拿py直接暴力打了表 拿了前几个数据
参考了这个大佬的思想https://blog.csdn.net/milkyyyyy/article/details/82490607
先看这个式子
我们就可以把题中的 N! 恰好大于 X^X转换在log下进行计算 当log的底数大于1时时递增的 所以
若 logax>logay 则 x>y
于是有了新的打表程序。。。。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int N = 5e6 + 5;
const int mod = 1e9 + 7;
double n, x, m;
int main ()
{
while(cin >> x)
{
n = m = 0;
x *= log(x);
while(1)
{
n += log(++m);
if(n > x)
break;
}
cout << m << endl;
}
return 0;
}
这个我挂了十多分钟把。。。出来全部结果
然后就可以愉快的交代码了。
#include<bits/stdc++.h>
using namespace std;
int main() {
long long a[15] = {10,94,892,8640,84657,834966,8267019,82052137,815725636,8118965902};
string ss;cin>>ss;
cout<<a[ss.size()-1]<<endl;
}
正解:
不会写。。
贴一个蔡队的正解代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll count(ll n)
{
if (n == 1) return 1;
return static_cast<ll>(ceil(0.5 * log10(2 * M_PI * n) + n * log10(n) - n * log10(M_E)));
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("1.in", "r", stdin);
freopen("1.out", "w", stdout);
#endif
ll x;
cin >> x;
ll cnt = static_cast<ll>(log10(x) * x) + 1;
ll l = 1, r = 1e12, ans;
while (l <= r)
{
ll m = l + r >> 1;
ll tmp = count(m);
// cerr << m << " " << tmp << endl;
if (tmp > cnt)
r = m - 1,
ans = m;
else
l = m + 1;
}
cout << ans << endl;
return 0;
}