img
2023年广东工业大学新生赛
A
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #include <bits/stdc++.h> using namespace std; int t,x,y,z,sum,ans;int main () { cin>>t; while (t--) { cin>>x>>y>>z; sum=(y+z)%7 ; ans=sum+x; if (ans%7 ==0 ) ans=7 ; else ans=(sum+x)%7 ; cout<<ans<<endl; } return 0 ; }
B
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #include <bits/stdc++.h> using namespace std; int n,m,k,sum,ans,a[100005 ],b[100005 ];string s; int main () { cin>>n>>m; while (m--) { cin>>k>>s; if (s=="AC" &&a[k]==0 ) { sum++; a[k]=1 ; ans+=b[k]; } else b[k]++; } cout<<sum<<" " <<ans<<endl; return 0 ; }
C
或5或9即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #include <bits/stdc++.h> using namespace std;#define ll long long #define endl "\n" void solve () { ll n ; cin>>n; if (n==2ll ) cout<<5 <<endl; else cout<<9 <<endl; } int main () { cin.tie (0 );cout.tie (0 );ios::sync_with_stdio (0 ); int t = 1 ; cin>>t; while (t--){ solve (); } }
D
思路没问题
左边的数字一定比右边的数字的5要少一些,最好也是等于
右边的数字一定要比左边的数字6要少一些,最好也是等于
因此可以先枚举6
如果右边比较多就是0了
接下来给左边乘上一样的6
然后×5,相等就输出答案
不然就是-1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 #include <bits/stdc++.h> using namespace std;#define ll long long #define endl "\n" void solve () { ll x,y; cin>>x>>y; ll ans =0 ; ll cnt1=0 ,cnt2=0 ; ll xx = x,yy=y; while (xx%6 ==0 ) xx/=6 ,cnt1++; while (yy%6 ==0 ) yy/=6 ,cnt2++; if (cnt1<cnt2) { cout<<-1 <<endl;return ; } for (ll i=0 ;i<cnt1-cnt2;i++){ x/=6 ;ans++; } while (x<y){ x*=5 ;ans++; } if (x==y) cout<<ans<<endl; else cout<<-1 <<endl; } signed main () { cin.tie (0 );cout.tie (0 );ios::sync_with_stdio (0 ); ll t = 1 ; cin>>t; while (t--){ solve (); } }
E
使得一个连续的段使得0和1的个数最多并且相等
想个思路,前缀和,不过我们完全可以把0看成-1吗,兄弟。这样不就变成了找区间和为0了
也就是两个部分前缀和为0即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 #include <bits/stdc++.h> using namespace std;#define ll long long #define endl "\n" void solve () { int n; cin>>n; vector<int > a (n) ; for (int &x:a)cin>>x; vector<int > pre (n,a[0 ]?1 :-1 ) ; for (int i=1 ;i<n;i++) pre[i] = pre[i-1 ]+(a[i]?1 :-1 ); map<int ,int > mp; mp[0 ] = -1 ; for (int i=0 ;i<n;i++){ if (mp.find (pre[i])!=mp.end ()) continue ; mp[pre[i]] = i; } int ans = 0 ; for (int i=0 ;i<n;i++){ int x = pre[i]; ans =max (ans,i-mp[x]); } cout<<ans<<endl; } int main () { cin.tie (0 );cout.tie (0 );ios::sync_with_stdio (0 ); int t = 1 ; while (t--){ solve (); } }
或者:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 #include <bits/stdc++.h> using namespace std;const int N = 1e5 + 10 ; int n;map<int , int > a; vector<int > v[N]; int main () { cin >> n; int sum = 0 ; int res = 0 ; for (int i = 1 ; i <= n; i++) { int x; cin >> x; if (x == 0 ) sum--; else sum++; if (!sum) res=max (res,i); if (!a[sum]) a[sum] = i; else res = max (res, i - a[sum]); } cout << res << endl; return 0 ; }
F
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 #include <bits/stdc++.h> using namespace std;#define pii pair<int,int> #define int long lon const int N = 2e5 +10 ; void solve () { int n,V; map<int ,int >mp; cin>>n>>V; vector<int >t (n); for (int i=0 ;i<n;i++){ cin>>t[i]; } sort (t.begin (),t.end ()); int mx=0 ; for (int i=n-1 ;i>=0 ;){ int j=i; while (t[j]==t[i]&&j>=0 )j--; mp[t[i]%V]=mp[(t[i]+1 )%V]+i-j; mx=max (mx,mp[t[i]%V]); i=j; } cout<<n-mx<<endl; } signed main () { ios::sync_with_stdio (0 ),cin.tie (0 ),cout.tie (0 ); int T (1 ) ; cin>>T; while (T--) { solve (); } return 0 ; }
G
前缀字符串
加后缀字符串
直接求解最大值即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #include <bits/stdc++.h> #define int long long #define endl "\n" using namespace std;int n,sumk,sumd,prek[100010 ],sufd[100010 ];char s[100010 ];signed main () { std::ios::sync_with_stdio (false ); cin>>n>>s+1 ; for (int i=1 ;i<=n;i++){ prek[i]=prek[i-1 ]; if (s[i]=='k' &&sumk==0 )sumk++; else if (s[i]=='i' &&sumk==1 )sumk++; else if (s[i]=='r' &&sumk==2 )sumk++; else if (s[i]=='a' &&sumk==3 )sumk++; if (sumk==4 )prek[i]+=4 ,sumk=0 ; } for (int i=n;i>=1 ;i--){ sufd[i]=sufd[i+1 ]; if (s[i]=='i' &&sumd==0 )sumd++; else if (s[i]=='k' &&sumd==1 )sumd++; else if (s[i]=='o' &&sumd==2 )sumd++; else if (s[i]=='d' &&sumd==3 )sumd++; if (sumd==4 )sufd[i]+=4 ,sumd=0 ; } int ans=0 ; for (int i=1 ;i<=n;i++) if (prek[i]&&sufd[i+1 ])ans=max (prek[i]+sufd[i+1 ],ans); cout<<ans<<endl; return 0 ; }
H
根据辗转相除法即可以得到与ai 无关
然后暴力枚举b和c数组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 #include <bits/stdc++.h> using namespace std;#define ll long long #define endl "\n" inline ll gcd (ll x, ll y) { return y == 0 ? x : gcd (y, x % y); } void solve () { ll n; cin>>n; vector<ll> a (n) ,b (n) ,c (n) ; for (ll &x:a) cin>>x; for (ll &x:b) cin>>x; for (ll &x:c) cin>>x; ll g = 0 ; sort (a.begin (),a.end ()); reverse (a.begin (),a.end ()); for (ll i=0 ;i<n-1 ;i++){ g= gcd (g,a[i]-a[i+1 ]); } ll an_1 = a[n-1 ]; ll mx = 0 ,mi = 2e18 ; for (ll i=0 ;i<n;i++){ for (ll j=0 ;j<n;j++){ ll ng = gcd (g,an_1+b[i]+c[j]); mx =max (mx,ng); mi = min (mi,ng); } } cout<<mi<<" " <<mx<<endl; } signed main () { cin.tie (0 );cout.tie (0 );ios::sync_with_stdio (0 ); ll t = 1 ; while (t--){ solve (); } }
I
当我们使用第i个骰子时,
Ⅰ.从前方直接到达该格子,若当前位置为j,则前方位置应为j-ai ,故dpj =min(dpj ,dp[j-ai ]+1);
Ⅱ.反弹到达该格子,若当前位置为j,则起始位置y满足方程式(n-y)+(n-j)=ai ,即y=2*n-ai -j,故
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 #include <bits/stdc++.h> #define int long long const int INF=1e10 ;using namespace std;int n,m;int a[1010 ];map<int ,int >dp; signed main () { ios_base::sync_with_stdio (false );cin.tie (0 );cout.tie (0 ); cin>>n>>m; for (int i=-1000 ;i<=1000 ;i++)dp[i]=INF; dp[0 ]=0 ; for (int i=1 ;i<=m;i++)cin>>a[i]; for (int i=1 ;i<=m;i++){ for (int j=n;j>=-1000 ;j--) { int x=j-a[i]; dp[j]=min (dp[j],dp[x]+1 ); int y=2 *n-a[i]-j; if (y<=n)dp[j]=min (dp[j],dp[y]+1 ); } } if (dp[n]!=INF)cout<<dp[n]<<endl; else cout<<"-1" <<endl;; }
J
贪心加优先队列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 #include <bits/stdc++.h> using namespace std;#define ll long long #define endl "\n" ll n,m,x,y; ll grid[1005 ][1005 ] ={0 }; ll vis[1005 ][1005 ] ={0 }; bool ifon (ll x,ll y) { return x>=0 &&x<n&&y>=0 &&y<m; } ll cal (ll md) { ll ans = md; for (ll i=0 ;i<n;i++) for (ll j=0 ;j<m;j++) vis[i][j] = 0 ; vis[x][y] = 1 ; priority_queue<pair<ll,pair<ll,ll>>,vector<pair<ll,pair<ll,ll>>>,greater<pair<ll,pair<ll,ll>>>> pq; pq.push ({0 ,{x,y}}); ll dx[4 ] = {-1 ,1 ,0 ,0 }; ll dy[4 ] = {0 ,0 ,-1 ,1 }; ll arr = 0 ; while (pq.size ()) { auto pp = pq.top (); pq.pop (); if (md<pp.first) { ans += pp.first-md; md = pp.first; } arr +=1 ; md += pp.first; ll nx = pp.second.first,ny = pp.second.second; for (ll i=0 ;i<4 ;i++) { ll tox = dx[i]+nx; ll toy = dy[i]+ny; if (!ifon(tox,toy)) continue ; if (vis[tox][toy]) continue ; vis[tox][toy] = 1 ; pq.push ({grid[tox][toy],{tox,toy}}); } } return ans; } void solve () { cin>>n>>m>>x>>y; x--;y--; for (ll i=0 ;i<n;i++) for (ll j=0 ;j<m;j++) cin>>grid[i][j]; ll st = grid[x][y]; grid[x][y] = 0 ; ll ans = cal (st); if (ans <= st){ cout<<"No cheating need." <<endl; } else cout<<ans<<endl; } signed main () { cin.tie (0 );cout.tie (0 );ios::sync_with_stdio (0 ); ll t = 1 ; while (t--){ solve (); } }
K
有一个点,就是如果分解质因数是后,小于n的话那么,那直接补1就行了,因为不会影响最大公倍数,只会影响和。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 #include <bits/stdc++.h> using namespace std;#define int long long void solve () { int cnt = 0 ; int n;cin >> n; while (n) { if (n == 1 ) { cout << cnt + 1 << "\n" ; return ; } for (int i = 2 ; i*i<= n; i++) { int nn = n; int l = 1 ; if (n % i == 0 ) { while (nn % i == 0 ) { nn /= i; l *= i; } if (l + n/l <= n) { cout << cnt + 1 << "\n" ; return ; } else { break ; } } } cnt++; n /= 2 ; } } signed main () { int n;cin >> n; while (n--) solve (); }
img