感觉还好,签到没有用到什么难的算法,水过几道签到题就挂机,贼拉爽哈哈哈
A题
逆向思维,假设所有的纸币加起来总共有sum元,s张,sum减去n元记为x元,
把x用尽量少的ss张纸币表示出来,ans = s - ss
注意:不能直接贪心,假设x = 60元,有50元纸币1张,20元纸币3张,显然不能直接用50元的,那怎么办呢? 搜索啊
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#include<bitset>
#include<vector>
using namespace std;
const int INF = 0x3f3f3f3f;
int T,sum,ans,ss,n;
int a[11],b[11] = {0,1,5,10,20,50,100,200,500,1000,2000};
void dfs(int sum,int t,int s)
{
if(sum == 0)
{
ss = min(s,ss);
return;
}
if(sum < 0 || t < 1) return;
int k = min(sum / b[t],a[t]);
dfs(sum - k * b[t],t - 1,s + k);
if(k > 0) dfs(sum - (k - 1) * b[t],t - 1,s + k - 1);
}
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
ans = sum = 0;
for(int i = 1;i <= 10; ++i)
{
scanf("%d",&a[i]);
ans += a[i];
sum += a[i] * b[i];
}
sum -= n;
ss = INF;
dfs(sum,10,0);
if(ss == INF) printf("-1\n");
else printf("%d\n",ans - ss);
}
return 0;
}
F题
这个题刚开始想简单了,直接看了大小关系改变小于等于1次的就是合法的
结果还没等交就出了组样例卡住了 1 2 7 1 3 4 5
所以就想怎么办呢?
记录相邻两个数的大小关系出现次数
记录隔一个数字的两个数的大小关系出现次数
如果大于等于(或小于等于)的出现次数满足>=正常的有序数列中的数字-1即可
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#include<bitset>
#include<vector>
using namespace std;
int a[100010];
int T,n;
int x1,x2,x3,y1,y2,y3;
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
int flag = 0;
x1 = x2 = x3 = y1 = y2 = y3 = 0;
for(int i = 1;i <= n; ++i) scanf("%d",&a[i]);
for(int i = 1;i < n; ++i)
{
if(a[i] > a[i + 1]) x1++;
if(a[i] < a[i + 1]) x2++;
if(a[i] == a[i + 1]) x3++;
}
for(int i = 1;i < n - 1; ++i)
{
if(a[i] > a[i + 2]) y1++;
if(a[i] < a[i + 2]) y2++;
if(a[i] == a[i + 2]) y3++;
}
if(x1 + x3 >= n - 2 && y1 + y3 >= n - 3) flag = 1;
if(x2 + x3 >= n - 2 && y2 + y3 >= n - 3) flag = 1;
if(flag) printf("YES\n");
else printf("NO\n");
}
return 0;
}
G题
给出n个点坐标问是否是正多边形
对正多边形不是很了解所以想了一会,其实判断正多边形只需要看边长相等即可
我没有想到这个,直接想,正多边形任意两点之间能构成的线段长度有多少种 n/2,扔到set里去个重即可
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#include<bitset>
#include<vector>
using namespace std;
set<int>q;
int T,x[110],y[110],n;
int jl(int k,int l)
{
return (x[k] - x[l]) * (x[k] - x[l]) + (y[k] - y[l]) * (y[k] - y[l]);
}
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
q.clear();
for(int i = 1;i <= n; ++i)
{
scanf("%d%d",&x[i],&y[i]);
for(int j = 1;j < i; ++j)
q.insert(jl(i,j));
}
if(q.size() == n / 2) printf("YES\n");
else printf("NO\n");
}
return 0;
}
H题
刚开始没看懂题
树上每个节点有一个清凉度,清凉度是一个关于节点度的函数
问能够组成树的最大清凉度是多少
后来想一颗n个点的树所有的度是2n-2,其中每个点的度>=1,所以只需要分配剩下的n-2个度就可以了
(有初始限定的完全背包)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#include<bitset>
#include<vector>
using namespace std;
int f[2200],a[2200];
int T,n,ans;
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i = 0;i < n - 1; ++i)
{
scanf("%d",&a[i]);
if(i) a[i] -= a[0];
}
for(int i = 0;i <= n; ++i) f[i] = -0x3f3f3f3f;
f[0] = a[0] * n;
for(int i = 1;i < n; ++i)
for(int j = i;j <= n - 2; ++j)
f[j] = max(f[j],f[j - i] + a[i]);
printf("%d\n",f[n - 2]);
}
return 0;
}
J题
eennn,这个题好坑,9s的时限,我不敢跑暴力一直拦着队友,后来发现他喵的暴力还真能过
正解是01字典树(有空看去吧)
L题
模拟,求一个不规则图形的表面积(除底面)
直接模拟就好
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#include<bitset>
#include<vector>
using namespace std;
int T,n,m;
int ans,a[60][60];
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
ans = 0;
for(int i = 1;i <= n; ++i)
for(int j = 1;j <= m; ++j)
{
scanf("%d",&a[i][j]);
if(a[i][j]) ans++;
}
for(int i = n; i > 1; --i)
for(int j = 1;j <= m; ++j)
ans += abs(a[i][j] - a[i - 1][j]);
for(int j = 2;j <= m; ++j)
for(int i = 1;i <= n; ++i)
ans += abs(a[i][j] - a[i][j - 1]);
for(int i = 1;i <= n; ++i)
ans += a[i][1] + a[i][m];
for(int j = 1;j <= m; ++j)
ans += a[1][j] + a[n][j];
printf("%d\n",ans);
}
return 0;
}