A. Number Transformation
题意:给定两个数x和y,询问是否存在a和b使得x*ba=y
思路:暴力求解
#include
using namespace std;
int fastpow(int a,int n)
{
int res=1;
while(n)
{
if(n&1)
{
res*=a;
}
a*=a;
n>>=1;
}
return res;
}
int main()
{
int t;
for(cin>>t;t;t--)
{
int x,y;
cin>>x>>y;
if(y<x||y%x!=0)
{
cout<<"0 0"<<endl;
continue;
}
else
{
int kk=y/x;
// cout<
for(int i=1;i<=100;i++)
{
for(int j=1;j<=100;j++)
{
if(fastpow(j,i)==kk)
{
cout<<i<<" "<<j<<endl;
goto o;
}
}
}
}
o:;
}
return 0;
}
B. Dictionary
题意:给定两个字母用来表示数字,两个字母一定不相同。ab表示1,ac表示2,az表示25
ba表示26 bc表示27以此类推,问你任意两个字母表示什么数字
思路:暴力求解
#include
using namespace std;
int main()
{
map<string,int> mp;
int cnt=1;
for(char a='a';a<='z';a++)
{
for(char b='a';b<='z';b++)
{
if(a==b)
continue;
string s="";
s+=a;s+=b;
mp[s]=cnt++;
}
}
int t;
for(cin>>t;t;t--)
{
string s;
cin>>s;
cout<<mp[s]<<endl;
}
return 0;
}
C. Infinite Replacement
题意:给定一个只包含一种字符‘a’的字符串s和一个字符串t,求将s中的任意字符‘a’替换后,算上原来的字符s一共能产生多少不同的字符串,如果无限多输出-1。
思路:分类讨论,如果t中含有字符‘a’有两种情况
1.t的长度为1,那么答案就是1
2.t的长度不是1,答案就是-1
t中不含有‘a’,设s的长度为k,答案就是2k
我没开longlong wa了一发
#include
using namespace std;
int main()
{
int k;
for(cin>>k;k;k--)
{
string s,t;
cin>>s>>t;
char a=s[0];
int len1=s.length();
int len2=t.length();
bool falg=false;
for(int i=0;i<len2;i++)
{
if(t[i]==a)
{
falg=true;
break;
}
}
if(falg&&len2>1)
{
cout<<-1<<endl;
continue;
}
else if(falg&&len2==1)
{
cout<<1<<endl;
continue;
}
else
{
cout<<(1ll<<len1)<<endl;
}
}
return 0;
}
D. A-B-C Sort
题意:
给定数组a,我们先把a用操作1装到数组b中
操作1:不断拿取数组a的最后一个元素放到数组b的中间位置,中间位置为x,如果b长度为奇数可以放在x/2+1或者x/2处
然后再用操作2把数组b放到数组c中
操作2:不断拿数组b的中间元素放到c的末尾处
如果c能够形成不严格递增序列输出YES否则输出NO
思路:模拟一下元素的存取发现,实际上A到C只不过是相邻元素可以交换位置,注意奇偶讨论
#include
using namespace std;
const int N = 2e5+100;
int a[N];
int b[N];
int main()
{
int k;
for(cin>>k;k;k--)
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
if(n&1)
for(int i=2;i<=n-1;i+=2)
{
if(a[i]>a[i+1])
{
swap(a[i],a[i+1]);
}
}
else
{
for(int i=1;i<=n-1;i+=2)
{
if(a[i]>a[i+1])
{
swap(a[i],a[i+1]);
}
}
}
bool falg=true;
for(int i=1;i<=n-1;i++)
{
if(a[i]>a[i+1])
{
falg=false;
}
}
if(falg)
{
cout<<"YES"<<endl;
}
else
{
cout<<"NO"<<endl;
}
}
return 0;
}
E. Breaking the Wall
题意:给定一个数组,每次可以选择一个位置x,a[x]的值-2,a[x-1]和a[x+1]的值-1
求让至少两个地方的数值小于等于0需要几次操作
思路:
首先思考答案可能产生在哪
1.间隔相邻的a[x+1]和a[x-1]
2.相邻的a[x]和a[x+1]
3.不相邻的a[i]和a[j]
对于第一种情况,我们显然让两个的和相加除二向上取整就好了
低于第三种情况,我们让最小的两个分别除二向上取整就好了
对于第二种情况,我们有a[x]位置除二向上取整,a[x+1]+1除二向上取整,(这两种是因为打击的连带效应,如果a[x]或者a[x]+1比相邻的大两倍那么自然把这一位置消除相邻位置也消除了)
a[i]+a[i+1]+2除二向上取整(这是处理相邻且不是两倍以上关系的情况)三种情况
#include
using namespace std;
int a[200000+100];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
int ans=1e9;
for(int i=1;i<=n-2;i++)
{
ans=min(ans,a[i]/2+a[i+2]/2+1);
}
for(int i=1;i<=n-1;i++)
{
ans=min(ans,max({(a[i]+1)/2,(a[i+1]+1)/2,(a[i]+a[i+1]+2)/3}));
}
sort(a+1,a+1+n);
ans=min((a[1]+1)/2+(a[2]+1)/2,ans);
cout<<ans<<endl;
return 0;
}
F. Desktop Rearrangement
模拟题,很简单没什么好说的。
#include
using namespace std;
char a[1100][1100];
int n,m,q;
int sum,col[1100];
int main()
{
cin>>n>>m>>q;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>a[i][j];
if(a[i][j]=='*')
{
sum++;
col[j]++;
}
}
}
while(q--)
{
int i,j;
cin>>i>>j;
if(a[i][j]=='*')
{
sum--;
col[j]--;
}
if(a[i][j]=='*')
a[i][j]='.';
else
a[i][j]='*';
if(a[i][j]=='*')
{
col[j]++;
sum++;
}
int cnt=sum/n;
int r=sum%n;
int t=0;
for(int j=1;j<=cnt;j++)
{
t+=col[j];
}
for(int i=1;i<=r;i++)
{
if(a[i][cnt+1]=='*')
t++;
}
cout<<sum-t<<endl;
}
return 0;
}
G. Remove Directed Edges
明天补,,