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 阅读(8) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效