“深圳计算科研院杯“E起来编程暨第三届湖北省赛
捏马人给痛没了,DEF思路晚点补!
总结:
现在我还很烂,但是我会努力变厉害的!
题解:
A Warm Welcome
签到题,直接输出就完了。
《能力要平均值·人形翻译机》队友速切。
代码:
#include <bits/stdc++.h>
typedef long long ll;
int main()
{
std::cout << "Shenzhen Institute of Computing Sciences";
return 0;
}
B Mr.Maxwell and attractions
贪心。
题目大意:
给你
n
,
m
,
t
,
k
n,m,t,k
n,m,t,k四个字母,
n
n
n代表有
n
n
n个户内景点;
m
m
m代表有
m
m
m个室外景点。然后输入
a
a
a数组,代表每一个室内景点能带来的愉悦度,然后输入
b
b
b数组,代表每一个户外景点能带来的愉悦度。有
t
t
t天,其中
k
k
k天只能下午出发。
已知:
- 户外景点下午出发愉悦度暂时变为80%;
- 所有景点重复访问将永久变为上次访问愉悦度的60%(反复叠加)。
思路:
优先队列+贪心。
总之其实是这样,天数循环中分为两个大块,能否早上出发
和非得下午出发不可
。
那么处理是这样,能早上出发的情况下为未折扣的户外和户内直接对比大小,如果优先户内了,那么由行动(户内)决定今天什么时候出发(下午),消耗k,让后面有更多选择。
反之折扣后的户外和户内直接对比,因为没得选择了,户外的都加debuff了。
一开始的错误思路:
直接让早上出发和下午出发两种,泾渭分明的两个while。
代码:
#include <bits/stdc++.h>
typedef long long ll;
const int MAXN = 1e5 + 10;
double a[MAXN], b[MAXN];
int main() {
int n, m, t, k;
scanf("%d%d%d%d", &n, &m, &t, &k);
for (int i = 1; i <= n; ++i) scanf("%lf", &a[i]);
for (int i = 1; i <= m; ++i) scanf("%lf", &b[i]);
double ans = 0;
std::priority_queue<double> que1, que2;
for (int i = 1; i <= n; ++i) que1.push(a[i]);
for (int i = 1; i <= m; ++i) que2.push(b[i]);
int tt = t - k;
for (int i = 1; i <= t; i++) {
double u = que1.top();
double v = que2.top();
que1.pop();
que2.pop();
if (i + k <= t) {
//意思是还能选择早上出发,不用折扣80%
//就是单纯的比大小,谁大去哪儿。
if (u > v) {
//优先去室内,那顺便让这一天变成下午出发,就能消耗k
ans += u;
que1.push(u * 0.6);
que2.push(v);
k--;
} else {
ans += v;
que1.push(u), que2.push(v * 0.6);
}
} else {
//必须消耗下午出发了
if (u > v * 0.8) {
ans += u;
que1.push(u * 0.6);
que2.push(v);
} else {
ans += 0.8 * v;
que1.push(u), que2.push(v * 0.6);
}
}
}
printf("%.2f\n", ans);
}
C Hamster and Equation
两个FOR循环。
F
(
x
1
,
x
2
)
=
K
∗
F
(
x
3
,
x
4
)
F(x1,x2) = K*F(x3,x4)
F(x1,x2)=K∗F(x3,x4)
代码:
#include <bits/stdc++.h>
typedef long long ll;
const int MAXN = 1e6 + 10, INF = 0x3f3f3f3f;
int st[MAXN];
int main()
{
int t; scanf("%d", &t);
while (t--)
{
int n, k; scanf("%d%d", &n, &k);
memset(st, 0, sizeof st);
int mini = INF, maxi = -INF;
for (int i = -n; i <= n; ++i)
for (int j = -n; j <= n; ++j)
{
int u = i * (i + 1) + j * (j + 1);
//循环暴力枚举x1/x2
st[u]++;
//记录F(x,y)==u的xy组数
mini = std::min(mini, u);
maxi = std::max(maxi, u);
}
if (k > 0)
{
ll ans = 0;
for (int i = mini; i <= maxi; ++i)
if (i % k == 0) ans += 1ll * st[i] * st[i / k];
printf("%lld\n", ans);
}
else if (k < 0)
printf("%lld\n", 1ll * st[0] * st[0]);
//负数特判
}
return 0;
}
总结教训:
帮忙看错误主要看代码,针对代码。 不能再用玄学bug法了…
D WA
set维护贪心选最小。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
vector<pair<int,int>>a;
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int n,k;cin>>n>>k;
string s;cin>>s;
int id=-1,id1=-1;
for(int i=0;i<n;i++)
if(s[i]=='a') {
if(id==-1) id=i;
id1=i;
}
if(id==-1) {
for(int i=0;i<k;i++)
s[i]='a';
cout<<k-1<<endl<<s<<endl;
return 0;
}
int l=id,r=id;
for(int i=id+1;i<=id1;i++)
{
if(s[i]=='a') {
r=i;
a.push_back({r-l-1,l+1});
l=i;
}
}
sort(a.begin(),a.end());
for(int i=0;i<a.size();i++)
{
if(a[i].first<=k) {
k-=a[i].first;
for(int j=a[i].second;j<min(a[i].first+a[i].second,n);j++)
s[j]='a';
}
else {
for(int j=a[i].second;j<min(a[i].second+k,n);j++)
s[j]='a';k=0;
}
}
// for(auto i:a)
// cout<<i.first<<" "<<i.second<<endl;
if(k) {
for(int i=id-1;i>=0;i--)
{
s[i]='a';k--;
if(!k) break;
}
for(int i=id1+1;i<min(id1+1+k,n);i++)
{
s[i]='a';
}
}
int ans=0;
for(int i=1;i<n;i++)
if(s[i]=='a'&&s[i-1]=='a') ans++;
cout<<ans<<endl<<s<<endl;
return 0;
}
E Pipeline Maintenance
矩阵树定理+打表除以n2找规律。
队友的200行巨长板子过了。
我只能您。
代码:
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
int MOD = 1e9 + 7;
template <class T> class Matrix
{
public:
int r, c;
vector < vector <T> > v;
Matrix()
{
r = c = 0;
v.clear();
}
Matrix(int a, int b): r(a), c(b)
{
v.resize(r + 1);
for (int i = 0; i <= r; ++i) v[i].resize(c + 1);
for (int i = 0; i <= r; ++i)
for (int j = 0; j <= c; ++j)
v[i][j] = 0;
}
void clear()
{
for (int i = 0; i <= r; ++i)
for (int j = 0; j <= c; ++j)
v[i][j] = 0;
}
vector <T> &operator [](int x) { return v[x]; }
Matrix <T> &operator +=(Matrix <T>);
Matrix <T> &operator -=(Matrix <T>);
Matrix <T> &operator *=(Matrix <T>);
Matrix <T> &operator %=(int);
};
template <class T> Matrix <T> operator +(Matrix <T> A, Matrix <T> B)//加
{
if (A.r != B.r || A.c != B.c) throw;
Matrix <T> C(A.r, A.c);
for (int i = 1; i <= A.r; ++i)
for (int j = 1; j <= A.c; ++j)
C[i][j] = (A[i][j] % MOD + B[i][j] % MOD) % MOD;
//!!此处有必要时添加取模:C[i][j] = (A[i][j] % MOD + B[i][j] % MOD) % MOD;!!
return C;
}
template <class T> Matrix <T> operator -(Matrix <T> A, Matrix <T> B)//减
{
if (A.r != B.r || A.c != B.c) throw;
Matrix <T> C(A.r, A.c);
for (int i = 1; i <= A.r; ++i)
for (int j = 1; j <= A.c; ++j)
C[i][j] = ((A[i][j] % MOD - B[i][j] % MOD) % MOD + MOD) % MOD;
//!!此处有必要时添加取模(注意负数):C[i][j] = ((A[i][j] % MOD - B[i][j] % MOD) % MOD + MOD) % MOD;!!
return C;
}
template <class T> Matrix <T> operator *(Matrix <T> A, Matrix <T> B)//乘
{
if (A.c != B.r) throw;
Matrix <T> C(A.r, B.c);
for (int i = 1; i <= A.r; ++i)
for (int j = 1; j <= A.c; ++j)
if (A[i][j])//稀疏矩阵优化
{
for (int k = 1; k <= B.c; ++k)
C[i][k] = (C[i][k] + (A[i][j] % MOD) * (B[j][k] % MOD)) % MOD;
//!!此处有必要时添加取模:C[i][k] = (C[i][k] + (A[i][j] % MOD) * (B[j][k] % MOD)) % MOD;!!
}
return C;
}
template <class T> Matrix <T> operator %(Matrix <T> A, int M)//模
{
Matrix <T> C(A.r, A.c);
for (int i = 1; i <= C.r; ++i)
for (int j = 1; j <= C.c; ++j)
C[i][j] = (A[i][j] % M + M) % M;
return C;
}
template <class T> Matrix <T> &Matrix <T>::operator +=(Matrix <T> A)//自加
{
if (A.r != r || A.c != c) throw;
for (int i = 1; i <= r; ++i)
for (int j = 1; j <= c; ++j)
v[i][j] = (v[i][j] % MOD + A[i][j] % MOD) % MOD;
//!!此处有必要时添加取模:v[i][j] = (v[i][j] % MOD + A[i][j] % MOD) % MOD;!!
return *this;
}
template <class T> Matrix <T> &Matrix <T>::operator -=(Matrix <T> A)//自减
{
if (A.r != r || A.c != c) throw;
for (int i = 1; i <= r; ++i)
for (int j = 1; j <= c; ++j)
v[i][j] = ((v[i][j] % MOD - A[i][j] % MOD) % MOD + MOD) % MOD;
//!!此处有必要时添加取模(注意负数):v[i][j] = ((v[i][j] % MOD - A[i][j] % MOD) % MOD + MOD) % MOD!!
return *this;
}
template <class T> Matrix <T> &Matrix <T>::operator *=(Matrix <T> B)//自乘
{
if (c != B.r) throw;
Matrix <T> C(r, B.c);
for (int i = 1; i <= r; ++i)
for (int j = 1; j <= c; ++j)
if (v[i][j])//稀疏矩阵优化
{
for (int k = 1; k <= B.c; ++k)
C[i][k] = (C[i][k] + (v[i][j] % MOD) * (B[j][k] % MOD)) % MOD;
//!!此处有必要时添加取模:C[i][k] = (C[i][k] + (v[i][j] % MOD) * (B[j][k] % MOD)) % MOD;!!
}
c = B.c;
v.clear(); v.resize(r + 1);
for (int i = 0; i <= r; ++i) v[i].resize(c + 1);
for (int i = 0; i <= r; ++i)
for (int j = 0; j <= c; ++j)
v[i][j] = C[i][j];
return *this;
}
template <class T> Matrix <T> &Matrix <T>::operator %=(int M)//自模
{
for (int i = 1; i <= r; ++i)
for (int j = 1; j <= c; ++j)
v[i][j] = ((v[i][j] % M) + M) % M;
return *this;
}
template <class T> bool operator ==(const Matrix <T> A, const Matrix <T> B)//判断相等
{
if (A.r != B.r || A.c != B.c) return 0;
for (int i = 1; i <= A.r; ++i)
for (int j = 1; j <= A.c; ++j)
if (A[i][j] != B[i][j]) return 0;
return 1;
}
//方阵类
template <class T> class Square: public Matrix <T>
{
public:
Square(): Matrix <T>() {}
Square(int n): Matrix <T>(n, n) {}
Square(int a, int b)
{
if (a != b) throw;
Matrix <T>::r = a, Matrix <T>::c = b;
Matrix <T>::v.resize(a + 1);
for (int i = 0; i <= a; ++i) Matrix <T>::v[i].resize(b + 1);
for (int i = 0; i <= a; ++i)
for (int j = 0; j <= b; ++j)
Matrix <T>::v[i][j] = 0;
}
Square(Matrix <T> A)
{
int mini = min(A.r, A.c);
Matrix <T>::v.resize(mini + 1);
Matrix <T>::r = Matrix <T>::c = mini;
for (int i = 0; i <= mini; ++i) Matrix <T>::v[i].resize(mini + 1);
for (int i = 1; i <= mini; ++i)
for (int j = 1; j <= mini; ++j)
Matrix <T>::v[i][j] = A[i][j];
}
operator Matrix <T>()
{
Matrix <T> A(Matrix <T>::r, Matrix <T>::c);
for (int i = 1; i <= Matrix <T>::r; ++i)
for (int j = 1; j <= Matrix <T>::c; ++j)
A[i][j] = Matrix <T>::v[i][j];
return A;
}
Square <T> &operator ^=(int);
};
//单位阵可以用A^0获取
template <class T> Square <T> operator ^(Square <T> A, int num)//乘方
{
int n = A.r;
Square <T> ans(n);
for (int i = 1; i <= n; ++i) ans[i][i] = 1;
while (num)
{
if (num & 1) ans = (ans * A) % MOD; //!!此处有必要时添加取模:ans = (ans * A) % MOD;!!
A = (A * A) % MOD;//!!此处有必要时添加取模:A = (A * A) % MOD;!!
num >>= 1;
}
return ans;
}
template <class T> Square <T> &Square <T>::operator ^=(int num)//乘方
{
int n = Matrix <T>::r;
Square <T> ans(n), temp(*this);
for (int i = 1; i <= n; ++i) ans[i][i] = 1;
while (num)
{
if (num & 1) ans = (ans * temp) % MOD;//!!此处有必要时添加取模:ans = (ans * temp) % MOD;!!
temp = (temp * temp) % MOD;//!!此处有必要时添加取模:temp = (temp * temp) % MOD;!!
num >>= 1;
}
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j)
Matrix <T>::v[i][j] = ans[i][j];
return *this;
}
template <class T> Square <T> operator &(Square <T> A, int num)//A^0~A^n求和
{
Square <T> temp(A.r * 2, A.c * 2);
for (int i = 1; i <= A.r; ++i)
for (int j = 1; j <= A.c; ++j)
temp[i][j] = A[i][j];
for (int i = A.c + 1; i <= A.c * 2; ++i) temp[i - A.c][i] = 1;
for (int i = A.r + 1; i <= A.r * 2; ++i) temp[i][i] = 1;
temp ^= num + 1;
Square <T> ans(A.r, A.c);
for (int i = 1; i <= A.r; ++i)
for (int j = 1; j <= A.c; ++j)
ans[i][j] = temp[i][j + A.c];
return ans;
}
int main()
{
Square < ll > A(2);
ll n; scanf("%lld", &n);
A[1][1] = 5, A[1][2] = -1, A[2][1] = 1, A[2][2] = 0;
Matrix < ll > p(2, 1);
p[1][1] = 1, p[2][1] = 0;
printf("%lld\n", ((A ^ (n - 1)) * p % MOD)[1][1] * n % MOD * n % MOD);
return 0;
}
F Meet in another world, enjoy tasty food!
差分维护。
题目大意:
排队的人排第几每回合损失耐心度多少,为零就走人了,而且他走了以后后面的人减去的耐心度少一。求最终走人顺序编号。
我题目都喂错了,稳点不要急躁。
代码:
#include <bits/stdc++.h>
typedef long long ll;
const int MAXN = 1e3 + 10;
ll a[MAXN], dif[MAXN], st[MAXN];
std::vector < ll > ans;
ll calc(ll a, ll b)
{
return a / b + (a % b != 0);
}
int main()
{
ll n; scanf("%lld", &n);
for (int i = 1; i <= n; ++i) scanf("%lld", &a[i]);
for (int i = 1; i <= n; ++i) dif[i] = 1;
ll s = 0, pp = 1;
while (pp <= n)
{
ll idx = 0, sidx = 0;
for (int j = 1; j <= n; ++j)
{
if (st[j]) continue;
s += dif[j];
if (!idx || calc(a[idx], sidx) > calc(a[j], s))
idx = j, sidx = s;
}
s = 0;
ll k = calc(a[idx], sidx);
int t = 0;
for (int j = 1; j <= n; ++j)
{
if (st[j]) continue;
s += dif[j];
a[j] -= (k - 1) * s + (s - t);
if (a[j] <= 0)
{
ans.push_back(j);
st[j] = pp++;
t++;
}
}
s = 0;
}
for (int i = 0; i < n; ++i)
printf("%lld ", ans[i]);
return 0;
}