2020 Multi-University Training Contest 3(待补
2020 Multi-University Training Contest 3
1004 Tokitsukaze and Multiple
-
思路:维护前缀和 用set统计个数
-
AC代码
#include <algorithm>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdio.h>
#include <string.h>
#include <string>
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
ll mult_mod(ll x, ll y, ll mod){
return (x * y - (ll)(x / (long double)mod * y + 1e-3) * mod + mod) % mod;
}
ll pow_mod(ll a, ll b, ll p){
ll res = 1;
while (b){
if (b & 1)
res = mult_mod(res, a, p);
a = mult_mod(a, a, p);
b >>= 1;
}
return res % p;
}
ll gcd(ll a, ll b){
return b ? gcd(b, a % b) : a;
}
const int N = 1e5 + 10;
int t, n, p, a, ans;
int sum[N];
set<int> st;
int main(){
#ifndef ONLINE_JUDGE
freopen("my_in.txt", "r", stdin);
#endif
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> t;
while (t -- ){
ans = 0;
sum[0] = 0;
st.clear();
cin >> n >> p;
for (int i = 1; i <= n; i ++ ){
cin >> a;
sum[i + 1] = (sum[i] + a) % p;
}
st.insert(sum[1]);
for (int i = 2; i <= n + 1; i ++ ){
if (st.count(sum[i])){
ans ++ ;
st.clear();
}
st.insert(sum[i]);
}
cout << ans << "\n";
}
return 0;
}
1005 Little W and Contest
-
思路:用并查集每次先找到两名认识选手所属集合 然后减去“122”“212”221“”222“这四种方案数 然后合并集合
-
AC代码
#include <algorithm>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdio.h>
#include <string.h>
#include <string>
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
ll mult_mod(ll x, ll y, ll mod){
return (x * y - (ll)(x / (long double)mod * y + 1e-3) * mod + mod) % mod;
}
ll pow_mod(ll a, ll b, ll p){
ll res = 1;
while (b){
if (b & 1)
res = mult_mod(res, a, p);
a = mult_mod(a, a, p);
b >>= 1;
}
return res % p;
}
ll gcd(ll a, ll b){
return b ? gcd(b, a % b) : a;
}
const int N = 1e5 + 10;
const int mod = 1e9 + 7;
int t, n, x, cnt1, cnt2, u, v;
int st1[N], st2[N], fa[N];
ll ans, res;
inline int find(int x){
return fa[x] == x ? x : find(fa[x]);
}
int main(){
#ifndef ONLINE_JUDGE
freopen("my_in.txt", "r", stdin);
#endif
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> t;
while (t -- ){
cnt1 = cnt2 = ans = res = 0;
cin >> n;
for (int i = 1; i <= n; i ++ ){
cin >> x;
if (x == 1){
st1[i] = 1;
st2[i] = 0;
cnt1 ++ ;
}
else{
st1[i] = 0;
st2[i] = 1;
cnt2 ++ ;
}
fa[i] = i;
}
ans = (1ll * cnt2 * (cnt2 - 1) * (cnt2 - 2) / 6 + 1ll * cnt2 * (cnt2 - 1) * cnt1 / 2) % mod;
cout << ans << "\n";
for (int i = 1; i < n; i ++ ){
cin >> u >> v;
u = find(u), v = find(v);
res = (res + 1ll * st1[u] * st2[v] * (cnt2 - st2[u] - st2[v])) % mod; // 1 2 2
res = (res + 1ll * st2[u] * st1[v] * (cnt2 - st2[u] - st2[v])) % mod; // 2 1 2
res = (res + 1ll * st2[u] * st2[v] * (cnt1 - st1[u] - st1[v])) % mod; // 2 2 1
res = (res + 1ll * st2[u] * st2[v] * (cnt2 - st2[u] - st2[v])) % mod; // 2 2 2
fa[u] = v, st1[v] += st1[u], st2[v] += st2[u]; // 合并
cout << (ans - res + mod) % mod << "\n";
}
}
return 0;
}
1008 Triangle Collision
-
思路:只考虑与x轴平行线 每次贡献为\(abs(\lfloor \frac{y}{\frac{\sqrt{3}}{2} * L} \rfloor)\) 再绕三角形中心依次旋转\(\frac{2}{3}\pi\) \(\frac{4}{3}\pi\) 即可算出碰撞次数(k没用long long wa了好几发
-
AC代码
#include <algorithm>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdio.h>
#include <string.h>
#include <string>
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
ll mult_mod(ll x, ll y, ll mod){
return (x * y - (ll)(x / (long double)mod * y + 1e-3) * mod + mod) % mod;
}
ll pow_mod(ll a, ll b, ll p){
ll res = 1;
while (b){
if (b & 1)
res = mult_mod(res, a, p);
a = mult_mod(a, a, p);
b >>= 1;
}
return res % p;
}
ll gcd(ll a, ll b){
return b ? gcd(b, a % b) : a;
}
const double eps = 1e-4;
const double pi = acos(-1.0);
const double alpha = 2.0 * pi / 3.0;
int t;
ll k;
double L;
struct point{
double x, y;
point(){}
point(double x_, double y_){
x = x_;
y = y_;
}
point operator +(const point &p){
return point(x + p.x, y + p.y);
}
point operator *(double k){
return point(k * x, k * y);
}
};
inline point rotate(point p){
point tp(p.x * cos(alpha) - p.y * sin(alpha), p.x * sin(alpha) + p.y * cos(alpha));
return tp;
}
point u, v;
inline ll check(double t){
ll ans = 0;
point tp = u + v * t;
ans += abs(floor(2.0 * tp.y / sqrt(3.0) / L));
tp.y -= sqrt(3.0) * L / 6.0;
tp = rotate(tp);
tp.y += sqrt(3.0) * L / 6.0;
ans += abs(floor(2.0 * tp.y / sqrt(3.0) / L));
tp.y -= sqrt(3.0) * L / 6.0;
tp = rotate(tp);
tp.y += sqrt(3.0) * L / 6.0;
ans += abs(floor(2.0 * tp.y / sqrt(3.0) / L));
return ans;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("my_in.txt", "r", stdin);
#endif
scanf("%d", &t);
while (t -- ){
scanf("%lf%lf%lf%lf%lf%lld", &L, &u.x, &u.y, &v.x, &v.y, &k);
double l = 0, r = 1e12;
while (r - l > eps){
double mid = (l + r) / 2.0;
if (check(mid) >= k)
r = mid;
else
l = mid;
}
printf("%.4lf\n", l);
}
return 0;
}
1009 Parentheses Matching
-
思路:用栈来进行匹配 同时记录位置 如果)但栈空 则将最左侧的位置变成( 若扫完字符串还有( 则将最右侧的*位置变成)
-
AC代码
#include <algorithm>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdio.h>
#include <string.h>
#include <string>
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
ll mult_mod(ll x, ll y, ll mod){
return (x * y - (ll)(x / (long double)mod * y + 1e-3) * mod + mod) % mod;
}
ll pow_mod(ll a, ll b, ll p){
ll res = 1;
while (b){
if (b & 1)
res = mult_mod(res, a, p);
a = mult_mod(a, a, p);
b >>= 1;
}
return res % p;
}
ll gcd(ll a, ll b){
return b ? gcd(b, a % b) : a;
}
const int N = 1e5 + 10;
int t, n, head, tail;
int pos[N];
bool flag;
char p[N], ans[N];
stack<int> st;
int main(){
#ifndef ONLINE_JUDGE
freopen("my_in.txt", "r", stdin);
#endif
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> t;
while (t -- ){
head = tail = 0;
flag = true;
while (!st.empty())
st.pop();
cin >> p;
n = strlen(p);
for (int i = 0; i < n; i ++ )
pos[i] = 0, ans[i] = ' ';
for (int i = 0; i < n; i ++ ){
if (p[i] == '*')
pos[ ++ tail ] = i;
else if (p[i] == '('){
st.push(i);
ans[i] = '(';
}
else{
if (!st.empty())
st.pop();
else{
if (head == tail){
flag = false;
break;
}
ans[pos[ ++ head ]] = '(';
}
ans[i] = ')';
}
}
while (!st.empty()){
int tmp = st.top();
st.pop();
if (head == tail || pos[tail] < tmp){
flag = false;
break;
}
ans[pos[tail -- ]] = ')';
}
if (flag){
for (int i = 0; i < n; i ++ )
if (ans[i] != ' ')
cout << ans[i];
}
else
cout << "No solution!";
cout << "\n";
}
return 0;
}