A - Rotate
直接输出
#include<bits/stdc++.h>
using namespace std;
int main()
{
string s;
cin>>s;
cout<<s[1]<<s[2]<<s[0];
}
B - Visibility
题目保证选择的点没有障碍,那么就以这个点向上下左右遍历计数即可。
最后答案减去3,因为多加三次该点
#include<bits/stdc++.h>
using namespace std;
const int N=105;
char a[N][N];
int main()
{
int h,w,x,y;
set<pair<int,int>>st;
cin>>h>>w>>x>>y;
for(int i=1;i<=h;i++)
for(int j=1;j<=w;j++)
cin>>a[i][j];
int res=0;
for(int i=y;i<=w;i++)
{
if(a[x][i]=='.') res++;
else break;
}
for(int i=y;i>0;i--)
{
if(a[x][i]=='.') res++;
else break;
}
for(int i=x;i<=h;i++)
{
if(a[i][y]=='.') res++;
else break;
}
for(int i=x;i>0;i--)
{
if(a[i][y]=='.')res++;
else break;
}
cout<<res-3;
}
C - ORXOR
因为是OR 和 XOR,结果几个数异或的结果大小与这几个数本身大小没有绝对的关系,我们看到N有20,所以可以利用状态压缩,遍历所有可能的分组方式,最后求得最大值。
#include<bits/stdc++.h>
using namespace std;
const int N=21;
typedef long long ll;
ll a[N];
int main()
{
int n;
cin>>n;
for(int i=0;i<n;i++)
cin>>a[i];
int res=INT_MAX;
for(int i=0;i<1<<(n-1);i++)
{
int orn=0;
int xorn=0;
for(int j=0;j<=n;j++)
{
if(j<n) orn|=a[j];
if(j==n || ((i>>j)&1)) xorn^=orn,orn=0;
}
res=min(res,xorn);
}
cout<<res;
}
D - Opposite
第一次做这样的题。
就是一个数学题,给定n个点,告诉你第0个点和第n/2个点的坐标,又知这n个点以逆时针方式表示,让你求第一个点的坐标。
很显然我们可以连接给定的两个点,那么他们的中点就是这个圆的中心,那么就可以利用第0个点求得一个向量,那么该向量逆时针旋转2π/n度,就是第一个点的坐标。
而对于向量旋转后的坐标,可以自行计算,属于高中知识,也可以背过拿来用
向量 a=(x,y) —> a’=(x’,y’)
顺时针旋转 α得到的向量的坐标为 (x′,y′)
x′ = sinα∗y + cosα∗x , y′ = cosα∗y − sinα∗x
逆时针旋转 α得到的向量的坐标为 (x′,y′)
x′ = sinα∗x - cosα∗y , y′ = cosα∗y + sinα∗x
#include<bits/stdc++.h>
using namespace std;
const int N=21;
typedef long long ll;
ll a[N];
int main()
{
int n;
cin>>n;
double xs,ys,xm,ym;
cin>>xs>>ys>>xm>>ym;
double xc=(xs+xm)/2.;
double yc=(ys+ym)/2.;
double x0=xs-xc;
double y0=ys-yc;
double div=(2*3.14159265358979)/n;
double x1=x0*cos(div) - y0*sin(div) + xc;
double y1=y0*cos(div) + x0*sin(div) + yc;
cout<<x1<<" "<<y1;
}
E - Traveler
非常好的一个DP问题。
大体思路为,要以颜色id递增顺序拿到球,那么必然要从这个颜色最左侧或最右侧出现的位置拿到,再去到另一边,那么就可以预先记录好各个颜色最左侧和最右侧出现的位置,然后DP[i][0/1]分别代表拿到第i种颜色球时,位于最左侧所花的时间和位于最右侧所花费的时间。
具体实现中,共三种情况分析,分别进行转移,代码更好理解。
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
typedef long long ll;
struct node{
ll dis,id;
}a[N];
ll dp[N][2];
ll l[N],r[N];
ll vis[N];
vector<ll>ti;
void update(ll prepos,ll predis,ll cur)
{
if(prepos<l[cur]){
dp[cur][0]=min(dp[cur][0],r[cur]-prepos+r[cur]-l[cur]+predis);
dp[cur][1]=min(dp[cur][1],r[cur]-prepos+predis);
}
else if(prepos>=l[cur] && prepos<=r[cur]){
dp[cur][0]=min(dp[cur][0],r[cur]-prepos+r[cur]-l[cur]+predis);
dp[cur][1]=min(dp[cur][1],prepos-l[cur]+r[cur]-l[cur]+predis);
}
else{
dp[cur][0]=min(dp[cur][0],prepos-l[cur]+predis);
dp[cur][1]=min(dp[cur][1],prepos-l[cur]+r[cur]-l[cur]+predis);
}
}
int main()
{
int n;
cin>>n;
ti.push_back(0);
memset(dp,0x3f,sizeof(dp));
for(int i=0;i<n;i++)
{
cin>>a[i].dis>>a[i].id;
if(!vis[a[i].id]){
ti.push_back(a[i].id);
vis[a[i].id]=1;
l[a[i].id]=a[i].dis;
r[a[i].id]=a[i].dis;
continue;
}
l[a[i].id]=min(l[a[i].id],a[i].dis);
r[a[i].id]=max(r[a[i].id],a[i].dis);
}
sort(ti.begin(),ti.end());
int len=ti.size();
dp[0][0]=0;
dp[0][1]=0;
for(int i=1;i<len;i++)
{
ll pre=ti[i-1];
ll cur=ti[i];
update(l[pre],dp[pre][0],cur);
update(r[pre],dp[pre][1],cur);
}
int t=ti[len-1];
ll ans=min(dp[t][0]+abs(l[t]),dp[t][1]+abs(r[t]));
cout<<ans;
}