A A+B Problem
思路:将数组输入之后复制一份进行排序,得到最大值,数组中非最大元素加上最大元素后输出,最大元素加上次大元素后输出
AC代码:
#include<bits/stdc++.h>
using namespace std;
int main(){
int n; cin>>n;
if(n==1){
int x;
cin>>x;
cout<<x;
return 0;
}
else{
vector<int> arr(n+1,0),brr(n+1,0);
for(int i=1;i<=n;i++){
cin>>arr[i];
brr[i]=arr[i];
}
sort(brr.begin()+1,brr.end());
for(int i=1;i<=n;i++){
if(arr[i]==brr[n]) cout<<arr[i]+brr[n-1]<<" ";
else cout<<arr[i]+brr[n]<<" ";
}
}
return 0;
}
B Komorebi的数学课
思路:用快速幂即可
AC代码:
#include<bits/stdc++.h>
using namespace std;
long long m;
long long quickpow(long long a,long long b){
long long sum=1;
while(b){
if(b&1)//与运算,可判断奇偶,详细见注释
sum=sum*a%m;//取模运算
a=a*a%m;
b>>=1;//位运算,右移,相当于除以2
//cout<<sum<<" "<<m<<endl;
}
return sum;
}
int main(){
long long n;
cin>>n;
m=(n+2);
cout<<quickpow(n,n);
return 0;
}
C 次佛锅
思路:难点在于口音er(bushi) 用map<string,int>来存就行,注意食材出现会有重复,所以每次要+=而不是直接赋值
AC代码:
#include<bits/stdc++.h>
using namespace std;
map<string,int> food;
int main(){
string s; getline(cin,s);
int x;
stringstream ss(s);
while(ss>>s>>x){
food[s]+=x;
}
int t;
cin>>t;
while(t--){
string ss;
cin>>ss;
cout<<food[ss]<<endl;
}
return 0;
}
D Setsuna的K数列
思路:通过观察可以发现,数组中每个数其实就是其下标的二进制位从2的x次方转到K的x次方,
所以只需将n转化为其对应的二进制字符串,在遍历字符串,若下标x的地方为1,则ans += pow(k,x)
最后输出ans即可
AC代码:
#include<bits/stdc++.h>
using namespace std;
const long long m = 1e9+7;
long long quickpow(long long a,long long b){
long long sum=1;
while(b){
if(b&1) sum=sum*a%m;
a=a*a%m;
b>>=1;
}
return sum;
}
int main(){
long long n,k;
cin>>n>>k;
string s;
while(n){
if(n%2){
s+="1";
}
else{
s+="0";
}
n/=2;
}
long long ans=0;
for(int i=0;i<s.size();i++){
if(s[i]=='1') ans += quickpow(k,i),ans%=m;
}
cout<<ans<<endl;
return 0;
}
E Wiki下象棋
思路:采用BFS即可,但需要注意,因为国际象棋和中国象棋共用一个棋盘,但走的规则不同,所以棋盘的矩阵和每次走的标记矩阵要分开储存,并且因为有多次询问,所以每次BFS时都要重置重新初始化标记数组
AC代码:(写的比较模板,结构体,check();都来了,可以简化,但我喜欢规范)
#include<bits/stdc++.h>
using namespace std;
int t;
int n,m,k,a,b,c,d;
int vis[303][303];
int mp[303][303];
int dx[8]={-2,-2,1,1,-1,-1,2,2};
int dy[8]={-1,1,-2,2,-2,2,-1,1};
int dx1[8]={-1,-1,0,0,0,0,1,1};
int dy1[8]={0,0,-1,1,-1,1,0,0};
struct node{
int x,y,cnt;
};
bool check0(int x,int y){
if(x>=1 && x<=n && y>=1 && y<=m && !vis[x][y] && !mp[x][y]) return true;
else return false;
}
bool check1(int x,int y){
if(!mp[x][y]) return true;
else return false;
}
int bfs(int op){
memset(vis,0,sizeof vis);
queue<node> q;
q.push({a,b,0});
vis[a][b]=1;
while(!q.empty()){
node now = q.front();
node next;
q.pop();
if(now.x == c && now.y == d) return now.cnt;
for(int i=0;i<8;i++){
next.x=now.x+dx[i]; next.y=now.y+dy[i];
if(op==0 && check0(next.x,next.y)){
next.cnt = now.cnt+1;
q.push(next);
vis[next.x][next.y]=1;
}
else if(op==1 && check0(next.x,next.y)){
int xx=now.x+dx1[i],yy=now.y+dy1[i];
if(check1(xx,yy)){
next.cnt = now.cnt+1;
q.push(next);
vis[next.x][next.y]=1;
}
}
}
}
return -1;
}
int main(){
cin>>t;
while(t--){
cin>>n>>m>>k>>a>>b>>c>>d;
memset(mp,0,sizeof mp);
while(k--){
int x,y;
cin>>x>>y;
mp[x][y]=1;
}
cout<<bfs(0)<<" "<<bfs(1)<<endl;
}
return 0;
}
F 黄金律法
思路:贪心,大的数要尽可能与小的数相乘,所以将数组弄成两个,一个降序一个升序,同下标的相乘再加给ans即可
AC代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
bool cmp(int a,int b){
return a>b;
}
void solve(){
int n;
cin>>n;
vector<int> arr(n),brr(n);
for(int i=0;i<n;i++) cin>>arr[i];
for(int i=0;i<n;i++) cin>>brr[i];
sort(arr.begin(),arr.end());
sort(brr.begin(),brr.end(),cmp);
int ans = 0;
for(int i=0;i<n;i++){
ans += arr[i]*brr[i];
}
cout<<ans<<endl;
}
signed main(){
int t;
cin>>t;
while(t--){
solve();
}
return 0;
}