题意:两个汉堡和一块肌肉合成一个鸡肉汉堡,两个汉堡和一块牛肉合成一个牛肉堡
思路:暴力枚举,鸡肉堡和牛肉堡的个数
代码:
#pragma GCC optimize(2)
#include <bits/stdc++.h>
using namespace std;
#define int long long
int s[3005 ][3005 ];
void solve () {
int n,a,b;
cin>>n>>a>>b;
int x,y;
cin>>x>>y;
int ans=0 ;
for (int i = 0 ; i <=a ; ++i) {
for (int j = 0 ; j <=b ; ++j) {
if (2 *i+2 *j<=n){
ans=max (ans,x*i+y*j);
}
}
}
cout<<ans<<endl;
}
signed main () {
int t;
cin>>t;
while (t--){
solve ();
}
}
题意:你可以将一个全是0的图进行转换,每次转换是将一2 * 2的局部矩阵转为1,问你能否在有限次操作下,将矩阵转换成给的那样
思路:暴力枚举即可,当区域内出现一个0时,那我们就不转换,其他的情况转换,最后我们检查一下两张图是否一致,记得记录一下转换的过程
代码:
#pragma GCC optimize(2)
#include <bits/stdc++.h>
using namespace std;
#define int long long
int g[55 ][55 ];
int s[55 ][55 ];
int n,m;
void print ( int x,int y) {
s[x][y]=1 ;
s[x+1 ][y]=1 ;
s[x][y+1 ]=1 ;
s[x+1 ][y+1 ]=1 ;
}
void printf () {
for (int i = 1 ; i <=n ; ++i) {
for (int j = 1 ; j <=m ; ++j) {
cout<<s[i][j]<<' ' ;
}
cout<<endl;
}
cout<<endl;
}
void solve () {
cin>>n>>m;
for (int i = 1 ; i <=n ; ++i) {
for (int j = 1 ; j <=m ; ++j) {
cin>>g[i][j];
}
}
vector<pair<int ,int >>ans;
for (int i = 1 ; i <n ; ++i) {
for (int j = 1 ; j <m ; ++j) {
if (g[i][j]==1 ){
if (s[i][j]==0 ){
print (i,j);
ans.push_back ({i,j});
}
else if (g[i+1 ][j]==0 ||g[i][j+1 ]==0 ||g[i+1 ][j+1 ]==0 ){
continue ;
}
else {
print (i,j);
ans.push_back ({i,j});
}
}
}
}
int vis=1 ;
for (int i = 1 ; i <=n ; ++i) {
for (int j = 1 ; j <=m ; ++j) {
if (s[i][j]!=g[i][j]){
cout<<"-1" ;
return ;
}
}
}
cout<<ans.size ()<<endl;
for (auto i:ans) {
cout<<i.first<<' ' <<i.second<<endl;
}
}
signed main () {
int t=1 ;
while (t--){
solve ();
}
}
题意:修建一个运输石油的管道,1代表十字路口,1米管道的钱是a,一米支架的费用是b,问如何修建会使花费的费用最低,求出最低费用。
思路:可以考虑贪心,先把他们修成全在上面的那种,然后对01这种位置考虑贪心,如果放下会价格低多少费用,需记录多个0的总费用,第二个思路比较简单实现,DP动态规划,F(i,j)表示第i个当前的状态为j时,所需费用最低是多少,当si为0时,我们就可以推出f[i+1,0]是由两种方式转移来的,一种是f[i,0],一种是f[i,1],同理,f[i+1,1]也是两种转移来的,如果si是1时,这个i只有一种状态,就是f[i,1],没有0状态,只能推出i+1,1是由f[i,1]转移而来的,最后求出f[n,0]:
代码:
#pragma GCC optimize(2)
#include <bits/stdc++.h>
using namespace std;
#define int long long
void solve () {
int n,a,b;
cin>>n>>a>>b;
string s;
cin>>s;
vector<vector<int >>f (n+4 ,vector <int >(2 ));
for (int i = 0 ; i <=n ; ++i) {
for (int j = 0 ; j <2 ; ++j) {
f[i][j]=1e18 ;
}
}
f[0 ][0 ]=b;
for (int i = 0 ; i <n ; ++i) {
if (s[i]=='0' ){
f[i+1 ][0 ]=min (f[i][0 ]+a+b,f[i+1 ][0 ]);
f[i+1 ][0 ]=min (f[i+1 ][0 ],f[i][1 ]+2 *a+b);
f[i+1 ][1 ]=min (f[i][0 ]+2 *a+2 *b,f[i+1 ][1 ]);
f[i+1 ][1 ]=min (f[i+1 ][1 ],f[i][1 ]+a+2 *b);
}
else {
f[i+1 ][1 ]=min (f[i+1 ][1 ],f[i][1 ]+a+2 *b);
}
}
cout<<f[n][0 ]<<endl;
}
signed main () {
int t=1 ;
cin>>t;
while (t--){
solve ();
}
}
题意:给n个二元组,任意排序,如果第一个元素或者第二个元素组成的序列是非递减的序列,那么这个数组是坏数组,问好的情况是多少个
思路:总共是n!种情况,有三类是坏的,第一元素是坏的,第二元素是坏的,第一第二元素都是坏的,那我们根据容斥原理求出第一种,第二种,还有第三种,我们第一种加上第二种,减去第三种,我们就可以得到所有不重复的坏的方案个数,我们怎么求呢,考虑到当我们排序之后,保证他是坏的,那么他还是有序的,因此我们能够交换的是相等的数字的位置,假设有3个3,那么可以有3!个,所以我们就记录数字个数即可,然后我们求他们的交集,即排序第一个元素之后,我们可以检查第二个元素是不是坏的,如果不是坏的,那么没有交集,如果有坏的,我们可以记录一下一个pair<>,然后再求一遍!,最后减去即可
代码:
#pragma GCC optimize(2)
#include <bits/stdc++.h>
using namespace std;
#define int long long
int fac[300005 ];
const int mod=998244353 ;
bool cmp1 (pair<int ,int >x,pair<int ,int >y) {
if (x.first!=y.first)
return x.first<y.first;
return x.second<y.second;
}
#define PII pair<int,int>
bool cmp2 (pair<int ,int >x,pair<int ,int >y) {
return x.second<y.second;
}
pair<int ,int > a[300005 ];
map<int ,int >vis1,vis2;
signed main () {
ios::sync_with_stdio (false ),cin.tie (0 ),cout.tie (0 );
int n;
cin>>n;
fac[0 ]=1 ;
for (int i = 1 ; i <=n ; ++i) {
fac[i]=(fac[i-1 ]*i)%mod;
}
for (int i=1 ;i<=n;i++){
cin>>a[i].first>>a[i].second;
vis1[a[i].first]++;
vis2[a[i].second]++;
}
for (int i = 1 ; i <=n ; ++i) {
if (vis1[a[i].first]==n||vis2[a[i].second]==n){
cout<<"0" ;
return 0 ;
}
}
int ans1=1 ;
for (int i = 1 ; i <=n ; ++i) {
if (vis1[i])
ans1=(ans1*fac[vis1[i]]%mod)%mod;
}
int ans2=1 ;
for (int i = 1 ; i <=n ; ++i) {
if (vis2[i]){
ans2=(ans2*fac[vis2[i]]%mod)%mod;
}
}
int res=(ans1%mod+ans2%mod)%mod;
sort (a+1 ,a+1 +n,cmp1);
for (int i = 2 ; i <=n ; ++i) {
if (a[i].second<a[i-1 ].second){
cout<<((fac[n]-res)%mod+mod)%mod;
return 0 ;
}
}
map<PII,int >mp;
int ans=1 ;
for (int i = 1 ; i <=n ; ++i) {
mp[{a[i].first,a[i].second}]++;
}
for (auto i:mp) {
ans=(ans%mod*fac[i.second]%mod)%mod;
}
cout<<((fac[n]-res+ans)%mod+mod)%mod;
}
题意:我们这是一个交互题,你要找出一个数x,在0到2^14-1之间,你可以询问两次,你每次询问是给出100个不同的数字,它反馈一个答案ans,这个答案是x与这100个数字的某个数字进行异或得到的,让你求出x
思路:假设我们第一次给出的数字是1到100,所有数的前7位二进制都是0,那么我们这个ans的前七位,即是x的前七位,然后我们让11111110000000与ans取&并集,即可以得到x的前七位,同理我们取后七位是0000000的数字,我们就可以求出后七位,然后我们取|即可以加起来
代码:
#pragma GCC optimize(2)
#include <bits/stdc++.h>
using namespace std;
#define int long long
void solve () {
}
signed main () {
cout<<"?" ;
for (int i = 1 ; i <=100 ; ++i) {
cout<<" " <<i;
}
cout<<endl;
::fflush (stdout);
int x;
cin>>x;
cout<<'?' ;
for (int i = 1 ; i <=100 ; ++i) {
cout<<' ' <<(i<<7 );
}
cout<<endl;
::fflush (stdout);
int y;
cin>>y;
int res=0 ;
res|=(x&(((1 <<7 )-1 )<<7 ));
res|=(y&((1 <<7 )-1 ));
cout<<"! " ;
cout<<res<<endl;
::fflush (stdout);
}
题意:两个操作,1操作是将a[x]+y,2操作是求i%x==y的a[i]的所有数字的和
思路:如果暴力的话是O(q * 500000),我们可以考虑分块,操作1时,我们可设一个数组ans[i][j],表示%x余y的数的和,那我们就可以对1-700每一个[i]进行遍历,求出%i余x%i的和,当我们进行操作2时,x<=700时,我们直接输出ans[x][y],如果大于700,我们可以进行一个暴力求解,复杂度在700左右,因此我们的复杂度就成了q根号q,即可过
代码:
#pragma GCC optimize(2)
#include <bits/stdc++.h>
using namespace std;
void solve () {
}
signed main () {
ios::sync_with_stdio (false ),cin.tie (0 ),cout.tie (0 );
int q;
cin>>q;
vector<int >a (5e5 +5 );
vector<vector<int >>ans (705 ,vector <int >(705 ));
while (q--){
int x,y,op;
cin>>op>>x>>y;
if (op==1 ){
a[x]+=y;
for (int i = 1 ; i <=700 ; ++i) {
ans[i][x%i]+=y;
}
}
else {
if (x<=700 )cout<<ans[x][y]<<'\n' ;
else {
int res=0 ;
for (int i = y; i <=(int )5e5 +5 ; i+=x) {
res+=a[i];
}
cout<<res<<'\n' ;
}
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】