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编辑  收藏  举报

导航