K、Many Littles Make a Mickle(签到题)
题目大意:有T组测试样例,每一组测试样例给一个n,一个m,从1-n层,第i层有i*i个房间,每个房间居住m个人,问一共能住多少人?
#include<bits/stdc++.h>
using namespace std;
void solve()
{
int n,m;
cin>>n>>m;
long long ans=0;
for(int i=1;i<=n;i++)
{
ans+=i*i;
}
ans*=m;
cout<<ans<<endl;
}
int main()
{
int t;
cin>>t;
while(t--)
solve();
return 0;
}
B、Continued Fraction
题目大意:有n组测试样例,每一组测试样例包括两个整数x,y。 输出一个n以及n个数a0-an满足题目所给的式子。
不难看出2=105/38,而红圈内的部分为(105%38)/38的倒数,设当前分子为x,分母为y,那么红圈内部分的分母又转化为求(x%y)/y,递归直到x为1即可。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int ans[N];
void solve()
{
int a,b;
int cnt=0;
cin>>a>>b;
while(1)
{
ans[cnt++]=a/b;//cnt存下一共有几个数
int temp;
temp=b;
b=a%b;
a=temp;
if(a==1)
break;
}
cout<<cnt-1<<" ";
for(int i=0;i<cnt;i++)
cout<<ans[i]<<" ";
cout<<endl;
}
int main()
{
int t;
cin>>t;
while(t--)
{
solve();
}
return 00;
}
L、It Rains Again
题目大意:有n个挡雨板,每个挡雨板的坐标点为x1,y1,x2,y2.即(x1,y1)与(x2,y2)的连线。问这n个挡雨板能挡住x轴多少长度。
不难看出,挡了多少雨和y轴没有关系,按照每块板的左x端点排序,累加长度并且去重即可。
每遍历完一个挡雨板,更新板子最靠后的末端last,每遍历到一个板,先加上x2-x1即该挡雨板的长,度,在判断x1-last为否小于0,如果小于0说明有重复部分减去重复部分即可。
注意:如果当前板的x2小于last直接跳过这个板子,说明板完全被覆盖了。
如图:
这种情况上面的板子被完全覆盖了,直接跳过。
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
struct node
{
int x1;
int y1;
int x2;
int y2;
}q[N];
bool cmp(node n1,node n2)
{
return n1.x1<n2.x1;
}
int main()
{
int n;
int a,b,c,d;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
cin>>a>>b>>c>>d;
if(a<c)
{
q[i].x1=a;
q[i].y1=b;
q[i].x2=c;
q[i].y2=d;
}
else
{
q[i].x1=c;
q[i].y1=d;
q[i].x2=a;
q[i].y2=b;
}
}
sort(q,q+n,cmp);
int last=q[0].x1;
long long ans=0;
for(int i=0;i<n;i++)
{
if(q[i].x2<=last)
continue;
ans+=q[i].x2-q[i].x1;
int add=last-q[i].x1;
if(add>0)
ans-=add;
last=q[i].x2;
}
cout<<ans;
}
A、Mio visits ACGN Exhibition
题目大意:给一个n行m列的01矩阵以及p,q,从(0,0)出发只能向右或向下走到(n,m),问有多少条路径其走过的0的个数不少于p,1的个数不少于q,输出取模后的条数。
看到取模就想到跑dfs必炸,还是跑了一遍试试,过了6个点炸了。
正确的做法应该是dp,f[i][j][k]表示走到(i,j)并且正好经过k个0的走法,但是三维数组开不了那么大,所以用滚动数组减少一维度变成f[j][k].
那么状态转移方程为:
a[i][j]=1,f[j][k]=f[j][k]+f[j-1][k];
a[i][j]=0,f[j][k]=f[j-1][k-1]+f[j][k-1];
i,j从小到大遍历,k从大到小遍历。如果j更小,表示f[j]已被更新则表示的是f[i][j]的状态,否则还没被更新表示的是f[i-1][j]的状态。k如果更小,则还没被更新。从(0,0)到(n,m)一共走过了n+m-1个点,最后累加符合条件的即可。
H、Hearthstone So Easy
题目大意:两个人玩游戏每个人都有n滴血以及一个k,轮流进行操作,操作分为两个阶段,①操作开始前,当前是第几轮就扣几滴血②选择恢复自己k滴血或减少对方k滴血。一个人血量先为0那么另一个人取胜。
两个人起始血量一样,如果两个人回合开始前的血量仍然一样的话,那么先手必败。后手是明白这一点的,所以如果先手回血,后手就让先手扣血,反之后手就让先手回血,这样子两人每回合开始血量都一样,那么后手必赢。所以除非先手在一开始就能杀死后手,后手必赢。
如果n为1的话先手也必输,特判一下。
#include<bits/stdc++.h>
using namespace std;
int t,n,k;
int main()
{
cin>>t;
while(t--)
{
cin>>n>>k;
if(k+1>=n)
cout<<"pllj"<<endl;
else
cout<<"freesin"<<endl;
}
return 0;
}
J、LRU
逆天题,本身不算难但是题面晦涩难懂极其逆天
题目大意:有n个数依次进入缓冲区,如果这个数已经存在那么就代替更早进入的这个数并且缓冲次数+1;如果没有这个数并且已经满了,就删除最早进入的数该数再进去,如果没满就进入。
求最小的缓冲区容量使得缓冲次数不小于k。
一眼二分找左边界,check函数用容器模拟即可。看代码吧
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
typedef pair<int,int> PII;
int a[N];
bool ans=false;
int res;
int n,k;
bool check(int mid)
{
int cnt=0;
set<PII>st;
map<int,int>mp;
for(int i=1;i<=n;i++)
{
if(mp.count(a[i]))//已经在里面了
{
cnt++;
st.erase(make_pair(mp[a[i]],a[i]));
mp[a[i]]=i;
st.insert(make_pair(i,a[i]));
continue;
}
else if(st.size()==mid)//没在里面并且满了
{
PII it=*st.begin();
st.erase(st.begin());
mp.erase(it.second);
st.insert(make_pair(i,a[i]));
mp[a[i]]=i;
continue;
}
else//没在里面并且没满
{
mp[a[i]]=i;
st.insert(make_pair(i,a[i]));
}
}
if(cnt>=k)
{
ans=true;
return true;
}
else
return false;
}
int main()
{
scanf("%d %d",&n,&k);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
int l=1,r=n,mid;
while(l<=r)
{
mid=(l+r)/2;
if(check(mid))
r=mid-1,res=mid;
else
l=mid+1;
}
if(!ans)
printf("cbddl\n");
else
printf("%d",l);
return 0;
}