一边做一边写的题解
把每个题我出现的问题展现出来 防止大家踩坑了
A
这个题真的是一个大水题 谁来都是
但是我竟然wa了一发。。。。
string str;
getline(cin,str);//整行读入string
char str2[1024];
cin.getline(str2,1024);//读入char数组
我第一次交的时候是用的gets()编译错误(所以避坑 pat也是会编译错误
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
const int N = 1e6 + 10;
string a;
int main()
{
getline(cin,a);
for (int i = 0; i < a.size(); i ++)
{
if (a[i] == '<') cout << "<";
else if (a[i] == '>') cout << ">";
else cout << a[i];
}
cout << endl;
return 0;
}
B
全乘在一起在%2当然不可能 每个数字%2就ok了
记得开long long
#include <algorithm>
#include <iostream>
using namespace std;
const int N = 5e6 + 10;
long long a[N], n, num;
int main()
{
cin >> n;
for (int i = 1; i <= n; i ++)
{
scanf("%lld",&a[i]);
while (a[i] != 0 &&a[i] % 2 == 0)
{
a[i] /= 2;
num++;
}
}
cout << num << endl;
}
C
快速幂
第n行第m个数就是C(n - 1, m)我知道这个公式但是不知道怎么用快速幂。。。
看题解说这是道模板题 呃。。
雀食我差的有点多 上模板把
求C(n,m)和A(n,m)
typedef long long ll;
const int inf=0x3f3f3f;
const int maxn=1e9+1;
const int mod=1e9+7;
ll a[];//数组大小注意,也要与下面初始化一致
ll Pow(ll a,ll b){
a%=mod;
ll ans = 1;
while(b)
{
if(b&1)
ans = (ans*a)%mod;
a = (a*a)%mod;
b/=2;
}
return ans%mod;
}
ll Quk(ll a,ll b){
a%=mod;
ll ans = 0;
while(b)
{
if(b&1)
ans = (ans+a)%mod;
a = (a+a)%mod;
b/=2;
}
return ans%mod;
}
ll C(ll n,ll m){
return Quk(Quk(a[n],Pow(a[n-m],mod-2)),Pow(a[m],mod-2))%mod;
}
ll A(ll n,ll m){
return Quk(a[n],Pow(a[n-m],mod-2))%mod;
}
int main()
{
a[0]=a[1]=1;
for(ll i=2;i<=1000000;i++)
a[i]=Quk(a[i-1],i);
//C,A使用均为前面数大
return 0;
}
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6+10;
const int mod = 1e9+7;
ll fact[N],infact[N];
ll qmi(ll a, ll k, ll p)
{
ll res = 1;
while (k)
{
if (k & 1) res = (ll)res * a % p;
a = (ll)a * a % p;
k >>= 1;
}
return res;
}
void init(int n)
{
fact[0] = infact[0] = 1;
for (int i = 1; i <=n; i ++ )
{
fact[i] = (ll)fact[i - 1] * i % mod;
infact[i] = (ll)infact[i - 1] * qmi(i, mod - 2, mod) % mod;
}
}
ll c(int a, int b )
{
return (ll)fact[a] * infact[b] % mod * infact[a - b] % mod;
}
int main()
{
int n;
cin>>n;
--n;
init(n);
ll ans=1;
for(int i=1; i<=n; ++i)
ans=ans*c(n,i)%mod;
cout<<ans<<endl;
}
D
找规律?
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
#include <queue>
using namespace std;
int a[30];
int main()
{
string s;
cin >> s;
for (int i = 0; i < s.size(); i ++) a[s[i] - 'a'] ++;
priority_queue<int, vector<int>, greater<int>> q;
for (int i = 0; i < 26; i ++)
{
if (a[i]) q.push(a[i]);
}
if (q.size() == 1) cout << q.top() << endl;
else {
int res = 0;
while (q.size() > 1)
{
int i = q.top(); q.pop();
int j = q.top(); q.pop();
res += i + j;
q.push(i + j);
}
cout << res << endl;
}
return 0;
}
E
四面体体积的公式
1.过一顶点的三向量设为a,b,c,所求四面体的体积就是|(a×b)·c/6
2.直接利用行列式计算
| 1 1 1 1 |
v =1/6 * det | x1 x2 x3 x4|
| y1 y2 y3 y4 |
| z1 z2 z3 z4|
#include <algorithm>
#include <iostream>
using namespace std;
const int N = 10;
double x[N], y[N], z[N];
int main()
{
for (int i = 1; i <= 4; i ++)
{
scanf("%lf%lf%lf",&x[i],&y[i],&z[i]);
}
double sum = x[2]*y[3]*z[4]+y[2]*z[3]*x[4]+x[3]*y[4]*z[2]-x[4]*y[3]*z[2]-x[3]*y[2]*z[4]-y[4]*z[3]*x[2];
sum -= x[1]*y[3]*z[4]+y[1]*z[3]*x[4]+x[3]*y[4]*z[1]-x[4]*y[3]*z[1]-x[3]*y[1]*z[4]-y[4]*z[3]*x[1];
sum += x[1]*y[2]*z[4]+y[1]*z[2]*x[4]+x[2]*y[4]*z[1]-x[4]*y[2]*z[1]-x[2]*y[1]*z[4]-y[4]*z[2]*x[1];
sum -= x[1]*y[2]*z[3]+y[1]*z[2]*x[3]+x[2]*y[3]*z[1]-x[3]*y[2]*z[1]-x[2]*y[1]*z[3]-y[3]*z[2]*x[1];
if (sum < 0) sum = (-sum) / 6;
else sum = sum / 6;
printf("%.12f\n",sum);
return 0;
}
F
逆序对
#include <algorithm>
#include <iostream>
using namespace std;
const int N = 1e6 + 10;
long long sum,t;
long long a[N], temp[N];
int n;
void merge_sort(int l, int r)//逆序对的模板(也不全是
{
if (l >= r) return ;
int mid = l + r >> 1;
merge_sort(l, mid);
merge_sort(mid + 1, r);
int k = 0, i = l, j = mid + 1;
while (i <= mid && j <= r)
{
if (a[i] < a[j]) temp[k ++] = a[i ++];//这里是<不是<=(前面与这个数相同的有算进去)
else {
temp[k ++] = a[j ++];
sum += mid - i + 1;
}
}
while (i <= mid) temp[k ++] = a[i ++];
while (j <= r) temp[k ++] = a[j ++];
for (int i = l, j = 0; i <= r; i ++, j ++) a[i] = temp[j];
}
int main()
{
scanf("%lld",&n);
for (int i = 1; i <= n; i ++)
{
scanf("%lld",&t);
a[i] = a[i - 1] + t;
if (a[i] <= 0) sum ++;//负数的自己不能和自己
}
merge_sort(1, n);
printf("%lld", (long long)n * (long long)(n + 1) / 2 - sum);
return 0;
}
H
我但是看见这道题是不敢下手(不知道怎么处理输入
#include <algorithm>
#include <iostream>
using namespace std;
string a;
string b = "name=\"csrfmiddlewaretoken\"";
int main()
{
while (cin >> a)
{
if (a == b)
{
cin >> a;
for (int i = 7; i < a.size() - 2; i ++) cout <<a[i];
break;
}
}
return 0;
}
J
背包dp
#include <algorithm>
#include <iostream>
using namespace std;
const int N = 1e4 + 10;
struct jg{
int a, b, p;
bool operator<(jg w)
{
return p < w.p;//按照用完优惠券之后价格 从小到大排序
}
};
jg q[N];
int n, k;
int f[N];//[现在的钱数] = 优惠后的钱数
int main()
{
cin >> n >> k;
for (int i = 0; i <= k; i ++) f[i] = i;
for (int i = 1;i <= n; i ++)
{
cin >> q[i].a >> q[i].b;
q[i].p = q[i].a - q[i].b;
}
sort(q + 1, q + n + 1);
for (int i = 1; i <= n; i ++)
{
for (int j = k; j >= q[i].a; j --)
f[j] = min(f[j], f[j - q[i].b]);
}
printf("%d",f[k]);
}