A题
思路:感觉跟模拟差不多,按照题意来就行,每踢一球之后进行判断,停止比赛的条件为:a的进球数量大于b的进球数量+b的剩余场数,反过来b也可以大于a的。出现了这种情况就直接返回,否则跑到最后输出-1即可,表示没有输出胜负。
#include<iostream>
#include<algorithm>
#include<math.h>
#include<map>
#include<string>
#include<string.h>
#include<queue>
#include<vector>
using namespace std;
const int N=1e5+5;
typedef long long ll;
void solve()
{
string s;
cin>>s;
s=" "+s;
int i;
int a=0;
int b=0;
int at=5;
int bt=5;
for(i=1;i<=10;i++){
if(i%2!=0){
if(s[i]=='1'){
a++;
}
at--;
}
else{
if(s[i]=='1'){
b++;
}
bt--;
}
if(a>b+bt||b>a+at){
cout<<i<<endl;
return;
}
}
cout<<-1<<endl;
}
int main()
{
int t;
t=1;
cin>>t;
while(t--){
solve();
}
system("pause");
return 0;
}
C题
思路:贪心的思想吧,就是每个教授分一份文章,当文章的引用量大于0的时候ans就++,最后输出ans即可。
#include<iostream>
#include<algorithm>
#include<math.h>
#include<map>
#include<string>
#include<string.h>
#include<queue>
#include<vector>
using namespace std;
const int N=1e5+5;
typedef long long ll;
ll a[N];
void solve()
{
int n;
int i;
cin>>n;
int ans=0;
for(i=0;i<n;i++){
cin>>a[i];
if(a[i]>0){
ans++;
}
}
cout<<ans<<endl;
}
int main()
{
int t;
t=1;
cin>>t;
while(t--){
solve();
}
system("pause");
return 0;
}
D题
思路:分类讨论点位于1,2,3,4四个区域的情况。
#include<iostream>
#include<map>
#include<algorithm>
#include<set>
#include<string>
#include<string.h>
#include<math.h>
#include<vector>
#include<queue>
#include<unordered_map>
typedef long long ll;
const int N=2e5+5;
ll mod=1e9+7;
using namespace std;
typedef pair<int,int> p;
void solve()
{
int x,y,xp,yp;
cin>>x>>y>>xp>>yp;
if(xp<=x&&yp<=y){
double ans =1.0 * max(xp, x - xp) * max(yp, y -yp) / (x * y);
printf("%.9lf\n",ans);
}
else if(xp<x&&yp>y){
double s1=(xp*y)*1.0/((x*y)+xp*(yp-y));
double s2=(x-xp)*y*1.0/((x*y)+(x-xp)*(yp-y));
double ans=max(s1,s2);
printf("%.9lf\n",ans);
}
else if(xp>=x&&yp>=y){
double s1=x*y;
double s2=xp*yp;
double ans=s1*1.0/s2;
printf("%.9lf\n",ans);
}
else if(xp>x&&yp<y){
double s1=(x*yp*1.0)/((x*y)+(xp-x)*yp);
double s2=(y-yp)*x*1.0/((x*y)+(xp-x)*(y-yp));
double ans=max(s1,s2);
printf("%.9lf\n",ans);
}
}
int main()
{
int t;
cin>>t;
while (t--)
{
solve();
}
system("pause");
return 0;
}
G题
思路:首先对于这题,我们验证一会可以发现,当某个数经过少量的操作次数后,可以得到f(x)=x,于是我们可以用set去记录,题目中k最大是1e9,但是上文中也曾提到,我们根本用不到这么多次操作,经过计算可以发现,最大的操作是20,而且数组长度最大是1e5,所以最大的计算量为1e7,不用怕超时,然后对于求和这个操作,我们可以先减去这个数,然后对x进行f(x)的操作,最后加上x。最后如果x的值不变了,就将其从set中除去。
#include<iostream>
#include<algorithm>
#include<math.h>
#include<map>
#include<string>
#include<string.h>
#include<queue>
#include<vector>
#include<set>
using namespace std;
const int N=1e5+5;
typedef long long ll;
ll a[N];
int f(int n)
{
return round(10*sqrt(n));
}
void solve()
{
int n,m;
cin>>n>>m;
int i;
set<int> z;
ll ans=0;
for(i=1;i<=n;i++){
cin>>a[i];
if(a[i]!=f(a[i])){
z.insert(i);
}
ans+=a[i];
}
z.insert(n+1);
for(i=0;i<m;i++){
int op;
cin>>op;
if(op==1){
int l,r,k;
cin>>l>>r>>k;
while(1){
int now=*(z.lower_bound(l));
if(now>r){
break;
}
for(int j=1;j<=min(20,k);j++){
ans-=a[now];
a[now]=f(a[now]);
ans+=a[now];
}
if(a[now]==f(a[now])){
z.erase(now);
}
l=now+1;
}
}
else{
cout<<ans<<endl;
}
}
}
int main()
{
int t;
t=1;
// cin>>t;
while(t--){
solve();
}
system("pause");
return 0;
}
H题
题目太长就不截图了。
思路:题目标题纯诈骗,这题跟dfs没有任何关系,因为我们知道一块完整的碎片(没有凸凹)的价值是10,现在给出n*n-1个拼图碎片的数据,想知道最后一块的价值,所以对于一块碎片,当其突出的时候,也就代表着,最终的那一块会少一部分,反之,凹进去的时候,最终的那一块会多一部分。
#include<iostream>
#include<algorithm>
#include<math.h>
#include<map>
#include<string>
#include<string.h>
#include<queue>
#include<vector>
#include<set>
using namespace std;
const int N=1e5+5;
typedef long long ll;
void solve()
{
int n;
cin>>n;
n*=n;
int i;
ll ans=10;
for(i=0;i<n-1;i++){
char a[4];
for(int j=0;j<4;j++){
cin>>a[j];
if(a[j]=='1'){
ans++;
}
if(a[j]=='2'){
ans--;
}
}
}
cout<<ans<<endl;
}
int main()
{
int t;
t=1;
cin>>t;
while(t--){
solve();
}
system("pause");
return 0;
}
K题
思路:通过列举样例我们可以找到类似的规律,我们可以将整个字符串进行100100100......类似的进行排列,然后将多余的1排在最后,计算最后那一部分的坏的字符串即可。
#include<iostream>
#include<algorithm>
#include<math.h>
#include<map>
#include<string>
#include<string.h>
#include<queue>
#include<vector>
#include<set>
using namespace std;
const int N=1e5+5;
typedef long long ll;
ll a[N];
void solve()
{
int n,m;
cin>>n>>m;
int x=n-m;
x/=2;
if(x==0){
cout<<n-2<<endl;
}
else{
cout<<max(0,m-x-1)<<endl;
}
}
int main()
{
int t;
t=1;
//cin>>t;
while(t--){
solve();
}
system("pause");
return 0;
}
M题
思路:dp,dp[i][j]表示给i个人分了j颗糖,然后枚举第i个人分到1-k颗糖,(k<=j)
#include<iostream>
#include<algorithm>
#include<math.h>
#include<map>
#include<string>
#include<string.h>
#include<queue>
#include<vector>
#include<set>
using namespace std;
const int N=1e5+5;
typedef long long ll;
double dp[505][505];
void solve()
{
int n,m;
int i,j,k;
cin>>n>>m;
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
for(k=1;k<=j;k++){
dp[i][j]=max(dp[i-1][j-k]+k*1.0/(m-(j-k)),dp[i][j]);
}
}
}
printf("%.6lf",dp[n][m]);
}
int main()
{
int t;
t=1;
//cin>>t;
while(t--){
solve();
}
system("pause");
return 0;
}