SMU Summer 2024 Contest Round 4
H and V
1.因为数据范围很小,可以考虑把所有情况枚举出来判断,也就是二进制枚举
2.对要删的行或列标记一下,然后统计合法的点验证即可
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
typedef pair<int,int> pii;
#define forn(i,n) for(int i=0;i<(int)n;i++)
#define x first
#define y second
#define all(v) v.begin(),v.end()
int dx[]={0,1,-1,0};
int dy[]={-1,0,0,1};
char a[10][10];
void solve()
{
int sum=0;
int h,w,k;cin>>h>>w>>k;
for(int i=0;i<h;i++)
for(int j=0;j<w;j++) {
cin>>a[i][j];
}
int n=h+w,ans=0;
map<int,int>fi,lk;//fi为行的标记,lk为列的标记
for(int i=0;i<(1<<n);i++){
int tot=0;//每次进来都记得重置一下
fi.clear();
lk.clear();
for(int j=0;j<n;j++)
{
if(i>>j &1){
if(j>=h) lk[j-h]=1;
else fi[j]=1;
}else {
if(j>=h) lk[j-h]=0;
else fi[j]=0;
}
}
//把要删的行和列标记一下
//遍历统计合法的#即可
for(int i=0;i<h;i++)
for(int j=0;j<w;j++)
{
if(a[i][j]=='#'&&!fi[i]&&!lk[j]) tot++;
}
if(tot==k) ans++;
}
cout<<ans;
}
signed main()
{
ios::sync_with_stdio(0),cin.tie(0);
int t=1;
//cin>>t;
while(t--) solve();
return 0;
}
Made Up
1.统计一下A中不同数字出现的数量,再统计一下Bcj不同数字的数量,然后遍历map,把数量相乘即可
void solve()
{
int n;cin>>n;
map<int,int>mp;
map<int,int>fi;
vector<int>a(n+1),b(n+1);
for(int i=1;i<=n;i++){
cin>>a[i];
fi[a[i]]++;
}
for(int i=1;i<=n;i++) cin>>b[i];
for(int i=1;i<=n;i++){
int x; cin>>x;
mp[b[x]]++;
}
int ans=0;
for(auto t:fi)
{
int p=t.x;
ans+=t.y*mp[p];
}
cout<<ans;
}
Red and Green Apples
1.为了避免讨论,我们可以在红苹果和绿苹果进行从大到小的排序后,取x个红和y个绿并且把所有无色的苹果都放到一个数组里,然后从大到小对这个数组排序,就避免了要讨论让这个无色的苹果涂成红色还是绿色
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
typedef pair<int,int> pii;
#define forn(i,n) for(int i=1;i<=(int)n;i++)
#define x first
#define y second
#define allr(v) v.rbegin(),v.rend()
int dx[]={0,1,-1,0};
int dy[]={-1,0,0,1};
char a[10][10];
void solve()
{
int xx,yy,a,b,c;
vector<int>ve;
cin>>xx>>yy>>a>>b>>c;
int p[a+1],q[b+1];
forn(i,a) cin>>p[i];
forn(i,b) cin>>q[i];
forn(i,c){
int x;cin>>x;
ve.push_back(x);
}
sort(p+1,p+a+1,greater<int>());
sort(q+1,q+b+1,greater<int>());
forn(i,xx) ve.push_back(p[i]);
forn(i,yy) ve.push_back(q[i]);
sort(allr(ve));
int ans=0;
for(int i=0;i<xx+yy;i++)
{
ans+=ve[i];
}
cout<<ans;
}
signed main()
{
ios::sync_with_stdio(0),cin.tie(0);
int t=1;
//cin>>t;
while(t--) solve();
return 0;
}
Sum of Divisors
1.我们举例从1-10,分别计算一下每个数字的贡献(做因子的个数✖️这个数字的大小)
2.对于数字1,1是每个数字的正因数,所以它的贡献就是1+2+3+....10
3.对于数字2,2是2 4 6 8 10的正因数,所以它的贡献是2+4+6+8+10=2(1+2+3+4+5),括号里一共有10/2个数
4.对于数字3,3是3 6 9的正因数,所以它的贡献是3+6+9=3(1+2+3),括号里有10/3个数
5.对于后面的数是同理的,那么可以发现每个数字括号里的个数为n/i,括号里就是一个等差数列,那么对于每一个数则可以推导出部分和为 i✖️(n/i)✖️(1+n/i)/2
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
typedef pair<int,int> pii;
#define forn(i,n) for(int i=1;i<=(int)n;i++)
#define x first
#define y second
#define allr(v) v.rbegin(),v.rend()
int dx[]={0,1,-1,0};
int dy[]={-1,0,0,1};
void solve()
{
int n;
int ans=0;
cin>>n;
for(int i=1;i<=n;i++) ans+=i*(n/i)*(1+n/i)/2;
cout<<ans;
}
signed main()
{
ios::sync_with_stdio(0),cin.tie(0);
int t=1;
//cin>>t;
while(t--) solve();
return 0;
}
Rem of Sum is Num
1.这题虽然推起来公式不难,但是对于细节上的处理我还是不是特别理解,先搬一下别人的题解。
#include<bits/stdc++.h>
using namespace std;
using i64 = long long;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
i64 n, k;
cin >> n >> k;
vector<i64> a(n + 1), pre(n + 1);
for (int i = 1; i <= n; i ++) {
cin >> a[i];
pre[i] = pre[i - 1] + a[i];
}
for (int i = 1; i <= n; i ++) {
pre[i] = (pre[i] - i) % k;
}
i64 ans = 0;
int len = min(k-1, n);
map<i64, i64> mp;
mp[0] = 1;
for (int i = 1; i <= n; i ++) {
if (i > len) mp[pre[i - k]]--;
ans += mp[pre[i]];
mp[pre[i]] ++;
}
cout << ans << '\n';
return 0;
}
posted on 2024-07-16 14:57 swj2529411658 阅读(7) 评论(0) 编辑 收藏 举报