打得状态很差的一场。。
A.
题目链接:
https://codeforces.com/contest/1243/problem/A
题意(大概)
input:
k:测试样例数
n:n块长方形平板
:第i块平板的长
从n块平板(第i(1<=i<=n)块长宽1)中选择任意块,使它们组成的正方形面积最大
题解:
(水题,按理说可以五分钟内切的那种,燃鹅当天我疯狂读错题???太久没打cf了噫呜呜噫反省!)
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int sum[1005];
int main()
{
int k;
scanf("%d",&k);
while(k--)
{
memset(sum,0,sizeof(sum));
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
int x;
scanf("%d",&x);
sum[x]++;
}
int ans=0;
for(int i=n;i>=1;i--)
{
sum[i-1]+=sum[i];
ans=max(ans,min(i,sum[i]));
}
printf("%d\n",ans);
}
return 0;
}
B1.
题目链接:
http://codeforces.com/contest/1243/problem/B1
题意(大概):
input:
k:测试样例数
n:s串和t串的长度
s、t:长度为n的串
问是否能通过一次(必须恰好是一次)交换使s、t串相等
交换规则:
选择i、j,1<=i,j<=n,i可以等于j,交换、
题解:
(水题,燃鹅我又一次读错了题???我仿佛瞎了一般没有看到【the values i and j can be equal or different】
不仅这样,我还把1e4的数组开成了1e3并且第一次RE以后检查了一遍数组大小信誓旦旦“这没有错啊!”
于是又倔强的RE了两发)
很容易发现能满足这个的情况有两种:
①s串本来就和t串相同,随便选第x位,让i=x,j=x交换也还是一样的
②s串和t串有两处不同,形式为:
??...a??...a
??...b??...b
也就是说这两处不同的位置就是i和j,应该满足s[i]=s[j],t[i]=t[j]
我代码写复杂了因为我一开始读错了题qwq
化简版在注释里
#include<bits/stdc++.h>
using namespace std;
#define ll long long
char s[10005];
char t[10005];
int dif[10005];
int main()
{
int k;
scanf("%d",&k);
while(k--)
{
int n;
scanf("%d",&n);
scanf("%s",s);
scanf("%s",t);
bool flag=true;
int tot=0;
for(int i=0;i<n;i++)
{
if(s[i]!=t[i])
{
dif[tot++]=i;
}
}
if(tot==2&&(s[dif[0]]!=s[dif[1]]||t[dif[0]]!=t[dif[1]]))
flag=false;
if(tot==1||tot>2)
flag=false;
if(flag)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}
/*
#include<bits/stdc++.h>
using namespace std;
#define ll long long
char s[10005];
char t[10005];
int main()
{
int k;
scanf("%d",&k);
while(k--)
{
int n;
scanf("%d",&n);
scanf("%s",s);
scanf("%s",t);
bool flag=true;
int tot=0;
int ii=-1,jj=-1;
for(int i=0;i<n;i++)
{
if(s[i]!=t[i])
{
tot++;
if(tot==1) ii=i;
else if(tot==2) jj=i;
if(tot>2) break;
}
}
if(tot==0)
printf("Yes\n");
else if(tot==2&&s[ii]==s[jj]&&t[ii]==t[jj])
printf("Yes\n");
else
printf("No\n");
}
return 0;
}
*/
B2.
题目链接:
http://codeforces.com/contest/1243/problem/B2
题意(大概):
B1稍微改动后的题目,从【必须交换且仅交换1次】变成【最多可以交换m次】,可以不交换,但m必须<=2n
问最后s串能否与t串相同
题解:
(我又一次RE了,4发....并且RE到了比赛结束一直莫有检查出来我漏写了一个erase语句
谁都会有这种沙雕情况嘛(๑>ڡ<)☆【并不会)
很容易想到只要s+t串中每一种出现了的字母都是偶数个的话就一定存在可行解
在这种成立情况下比方说我在第i位发现了s[i]!=t[i]
那么一定存在一个j>i,满足s[j]!=t[j]&&(s[j]==s[i] || t[j]==s[i])
如果是s[j]==s[i]像B1题一样直接一次交换(swap s[j],t[i])即可:
x...x x...y
y...b x...b
如果是t[j]==s[i]那么两次交换(swap s[i],t[i];swap s[i],t[j])即可:
x...b y...b x...b
y...x x...x x...y
最多也就2n次,是绝对满足条件的
我用的set实现,稍微有些麻烦了,要考虑i和j对调以后对j的影响
#include<bits/stdc++.h>
using namespace std;
#define ll long long
char s[55];
char t[55];
int hm[30];
set<int> ss[30],st[30];
set<int>::iterator it;
pair<int,int> pr[125];
int main()
{
int k,n;
scanf("%d",&k);
while(k--)
{
scanf("%d",&n);
for(int i=0; i<26; i++)
{
hm[i]=0;
ss[i].clear();
st[i].clear();
}
scanf("%s",s);
scanf("%s",t);
for(int i=0; i<n; i++)
{
hm[s[i]-'a']++;
hm[t[i]-'a']++;
if(s[i]!=t[i])
{
int x=s[i]-'a';
ss[x].insert(i);
x=t[i]-'a';
st[x].insert(i);
}
}
bool flag=true;
for(int i=0; i<26; i++)
{
if(hm[i]%2!=0)
{
flag=false;
break;
}
}
if(!flag)
printf("No\n");
else
{
int ans=0;
for(int i=0; i<n; i++)
{
if(s[i]!=t[i])
{
int x=s[i]-'a';
int y=t[i]-'a';
it=ss[x].begin();
ss[x].erase(it);
it=st[y].begin();
st[y].erase(it);
//ss[x].pop();
//st[y].pop();
if(ss[x].size()>0)
{
//int loc=ss[x].top();ss[x].pop();
it=ss[x].begin();
int loc=*it;
ss[x].erase(it);
pr[ans].first=loc+1;
pr[ans].second=i+1;
ans++;
s[loc]=y+'a';
if(s[loc]!=t[loc])
{
//ss[y].push(loc);
ss[y].insert(loc);
}
else
{
st[t[loc]-'a'].erase(loc);
}
}
else
{
pr[ans].first=i+1;
pr[ans].second=i+1;
ans++;
//int loc=st[x].top();st[x].pop();
it=st[x].begin();
int loc=*it;
st[x].erase(it);
pr[ans].first=i+1;
pr[ans].second=loc+1;
ans++;
t[loc]=y+'a';
if(s[loc]!=t[loc])
{
//st[y].push(loc);
st[y].insert(loc);
}
else
{
ss[s[loc]-'a'].erase(loc);
}
}
}
}
printf("Yes\n%d\n",ans);
for(int i=0; i<ans; i++)
{
printf("%d %d\n",pr[i].first,pr[i].second);
}
}
}
return 0;
}
C.
题目链接:
http://codeforces.com/contest/1243/problem/C
题意(大概):
input:
n(1<=n<=1e12)
n块连续的瓷砖(标号为[1,n]),满足( | i - j | > 0 )&&( n % | i - j | ==0 )的瓷砖i和瓷砖j颜色必须相同
问最多能涂多少种颜色
题解:
稍微推一下就能猜到了:假如n只有一种质因子的话ans=该质因子,否则ans=1
燃鹅我忘了特判n=1wa了一发并因此怀疑了自己很久,心痛
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main()
{
ll n;
scanf("%I64d",&n);
if(n==1)
{
printf("1\n");
}
else
{
int tot=0;
ll ans=0;
if(n%2==0)
{
tot++;
ans=2;
while(n%2==0)
{
n/=2;
}
}
for(ll i=3;i*i<=n;i++)
{
if(n%i==0)
{
tot++;
ans=i;
while(n%i==0)
{
n/=i;
}
}
}
if(n>1)
{
tot++;
ans=n;
}
if(tot>1)
{
printf("1\n");
}
else
{
printf("%I64d\n",ans);
}
}
return 0;
}