暑期第5周解题报告5篇(8月9日-8月15日)

/**
题目:
杭电2021-8-10
2021“MINIEYE杯”中国大学生算法设计超级联赛(7)
1008 Smzzl with Greedy Snake

题意:
告诉你贪吃蛇一开始在的位置x,y以及贪吃蛇一开始的头的朝向
告诉你食物的位置坐标
贪吃蛇按顺序吃完给出的n个食物
要求贪吃蛇吃每一个食物的时间最少
输出贪吃蛇的移动,f前进,c顺时针转动,u逆时针转动
  
思路:
要求贪吃蛇吃每一个食物的时间最少,而不是总时间最少
对于每一次食物的出现,判断这个食物在贪吃蛇的哪个位置,总共有16种
以及吃这个食物最少需要转动几次头
这题一开始用一个string ans来记录答案,最后输出整个ans,但是会超时
改成每次判断完方向后直接输出此次的答案则不会超时
会卡cin,cout
用string(cnt,'a')可以输出一个由cnt个‘a'的字符串
**/

#include<iostream>
using namespace std;
const int N=1e5+5;
struct node{
	int x;
	int y;
}a[N];
int main()
{
	ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0); 
	int t;
	cin >> t;
	while(t--){
		int x,y,d;
		cin >> x >> y >> d;
		int n;
		cin >> n;
		for(int i=1;i<=n;i++){
			cin >> a[i].x >> a[i].y;
		}
		string ans="";
		for(int i=1;i<=n;i++){
			int xx=a[i].x;
			int yy=a[i].y;
			if(d==0){
				if(xx<x && yy>y){
					cout << string(yy-y,'f'); 
					cout << 'u';
					cout << string(x-xx,'f');			
					d=3; 
				}
				else if(xx<x && yy<y){
					cout << 'u';
					cout << string(x-xx,'f');
					cout << 'u';
					cout << string(y-yy,'f');
					d=2;
				}
				else if(xx>x && yy>y){
					cout << string(yy-y,'f');
					cout << 'c';
					cout << string(xx-x,'f');
					d=1;
				}
				else if(xx>x && yy<y){
					cout << 'c';
					cout << string(xx-x,'f');
					cout << 'c';
					cout << string(y-yy,'f');
					d=2;
				}
			}
			else if(d==1){
				if(xx<x && yy>y){
					cout << 'u';
					cout << string(yy-y,'f');
					cout << 'u';
					cout << string(x-xx,'f');
					d=3;
				}
				else if(xx<x && yy<y){
					cout << 'c';
					cout << string(y-yy,'f');
					cout << 'c';
					cout << string(x-xx,'f');
					d=3;
				}
				else if(xx>x && yy>y){
					cout << string(xx-x,'f');
					cout << 'u';
					cout << string(yy-y,'f');
					d=0;
				}
				else if(xx>x && yy<y){
					cout << string(xx-x,'f');
					cout << 'c';
					cout << string(y-yy,'f');
					d=2;
				}
			}
			else if(d==2){
				if(xx<x && yy>y){
					cout << 'c';
					cout << string(x-xx,'f');
					cout << 'c';
					cout << string(yy-y,'f');
					d=0;
				}
				else if(xx<x && yy<y){
					cout << string(y-yy,'f');		
					cout << 'c';
					cout << string(x-xx,'f');
					d=3;
				}
				else if(xx>x && yy>y){
					cout << 'u';
					cout << string(xx-x,'f');
					cout << 'u';
					cout << string(yy-y,'f');
					d=0;
				}
				else if(xx>x && yy<y){
					cout << string(y-yy,'f');
					cout << 'u';
					cout << string(xx-x,'f');
					d=1;
				}
			}
			else if(d==3){
				if(xx<x && yy>y){
					cout << string(x-xx,'f');
					cout << 'c';
					cout << string(yy-y,'f');
					d=0;
				}
				else if(xx<x && yy<y){
					cout << string(x-xx,'f');
					cout << 'u';
					cout << string(y-yy,'f');
					d=2;
				}
				else if(xx>x && yy>y){
					cout << 'c';
					cout << string(yy-y,'f');
					cout << 'c';
					cout << string(xx-x,'f');
					d=1;
				}
				else if(xx>x && yy<y){
					cout << 'u';
					cout << string(y-yy,'f');
					cout << 'u';
					cout << string(xx-x,'f');
					d=1;
				}
			}
			x=xx;
			y=yy;
		}
		cout << endl;
	}
	return 0;
}
/**
题目:
杭电2021-8-10
2021“MINIEYE杯”中国大学生算法设计超级联赛(7)
1003 Fall with Trees

题意:
给出二叉树的根节点以及其两个子节点在坐标系中的坐标
要求整个二叉树的凸包
也就是上面的三角形+下面每一层的梯形的面积
  
思路:
可以把三角形也看成梯形,因为面积的计算也是(0+底)*h/2
所以除了最后的一个梯形的下底,其他的底都要计算两边
设x是一开始两个子节点之间的距离
一半的距离就是x/2,设为xx
那么下面的每一层依次增加2*xx/2
根据等比数列求和公式和面积公式即可得出
**/

#include<iostream>
using namespace std;
double qpow(double a,int b){//快速幂
	double s=1;
	for(;b;b>>=1){
		if(b&1) s=s*a;
		a=a*a;
	}
	return s;
}
int main()
{
	ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0); 
	int t;
	cin >> t;
	while(t--){
		int k;
		cin >> k;
		int tx,ty,x1,y1,x2,y2;
		cin >> tx >> ty >> x1 >> y1 >> x2 >> y2;
		double h=ty-y1;
		double x=x2-x1;
		double ans;
		if(k>=3) ans=(4*k-10+0.5*3*qpow(0.5,k-3))*h*x*0.5;//判断一下是否有梯形
		else ans=x*h*0.5;
		printf("%.3f\n",ans);
	}
	return 0;
 } 
/**
题目:
杭电2021-8-10
2021“MINIEYE杯”中国大学生算法设计超级联赛(7)
1012 Yiwen with Sqc

题意:
字符串s中,l到r之间字符c的个数记为sqc(s,l,r,c)
要计算从a到z,i从1到n,j从i到n的sqc平方和
  
思路:
dp[i]表示所有以i结尾的所有字符串的答案总和
每多一个字符后,原先有cnt个字符s[i],现在有cnt+1个
增加的即为(cnt+1)^2-cnt^2=2*cnt+1
对于前i个字符串,增加为sum{1-i}(2cnt+1)
对于一个字符串,维护s[i]之前出现的次数即为每次+1
维护i个字符即为每次+i 
**/

#include<iostream>
#include<string.h>
#define int long long
typedef long long ll; 
using namespace std;
const int mod=998244353;
const int N=1e5+5;
int dp[N];
int sum[N];
int ans;
signed main()
{
	int t;
	cin >> t;
	while(t--){
		string s;
		cin >> s;
		ans=0;
		memset(sum,0,sizeof(sum));
		int len=s.length();
		for(int i=0;i<len;i++){
			int x=s[i]-'a';
			dp[i]=(dp[i-1]+2*sum[x]+i+1)%mod;
			sum[x]=(sum[x]+i+1)%mod;
			ans=(ans+dp[i])%mod;
		}
		cout << ans << endl;
	}
	return 0;
 } 
/**
题目:
杭电2021-8-12
ICPC North Central NA Contest 2020 
H Digital Speedometer

题意:
告诉tf,tr
每次读入一个数,根据这个数所在的范围确定它对应的值
https://ac.nowcoder.com/acm/contest/18459/H
  
思路:
这一题主要是题目没有读明白
第三点的判断应该是abs(la-down)与abs(la-up)的比较
**/

#include<iostream>
using namespace std;
int main()
{
	double tf,tr;
	cin >> tf >> tr;
	double x;
	int la=0;
	while(cin >> x){
		int down=x;
		int up=down+1;
	    double l=down+tf;
		double r=down+tr;
		if(x<1 && x>0){
			la=1;
		}
		else{
			if(x<l){
				la=down;
			}
			else if(x>r){
				la=up;
			}
			else if(abs(la-down)<abs(la-up)){//注意这一点
				la=down;
			}
			else{
				la=up;
			}
		}
		cout << la << endl;
	}
	return 0;
 } 
/**
题目:
codeforces2021-8-9
Round #737(Div. 2)
C Moamen and XOR

题意:
给定n,k,求数组所有元素为非负数且<2^k,且满足条件a1&a2&a3...&an>=a1^a2^a3..^an的数组个数
  
思路:
对于某一位上的异或结果: 
如果1的个数是奇数,则异或结果为1
如果1的个数为偶数或者0个,则异或结果为0

对于某一位上的与运算结果:
如果全为1,则与运算结果为1
如果有一个不为1,则与运算结果为0

对n的奇偶性进行分类讨论
如果为奇数
当全为1时,相等
当不全为1时,1的个数为奇数时相等,否则与运算小于异或运算
如果为偶数
当全为1时,与运算大于异或运算,已经大于,后面的随便选 

对于某一位,不是全1的情况,与运算结果是0
这时为了保证异或运算不大于与运算,则异或运算也为0
即必须满足有偶数个1
**/ 
#include<iostream>
#define int long long //要用ll 
typedef long long ll; 
using namespace std;
const int N=2e5+5;
const int mod=1e9+7;

int fact[N],infact[N]; 
int n,m;

int qmi(int a,int n){//快速幂 
	int res=1;
	while(n){
		if(n&1) res=res*a%mod;
		a=a*a%mod;
		n>>=1;
	}
	return res%mod;
}

void init(){
	fact[0]=1;//0的阶乘是1 
	infact[0]=1;
	//对于每一个数n进行计算
	for(int i=1;i<N;i++){
		//根据定义求阶乘,注意每次都要取模
		fact[i]=fact[i-1]*i%mod;
		//费马小定理求i逆元
		infact[i]=infact[i-1]*qmi(i,mod-2)%mod; 
	} 
}

int calc(int a,int b){//组合数学 
	return (fact[a]%mod*infact[b]%mod*infact[a-b]%mod)%mod;	
}

void solve(){
	cin >> n >> m;
	int res=0;
	if(n%2){//n为偶数 
		int sum=1;
		for(int i=0;i<=n-1;i=i+2){
			sum=(sum+calc(n,i))%mod;
		}
		res=qmi(sum,m); 
	}
	else{//n为奇数 
		int sum=0;
		for(int i=0;i<=n-2;i=i+2){
			sum=(sum+calc(n,i))%mod;
		}
		res=qmi(sum,m); 
		for(int i=1;i<=m;i++){
			res=(res+qmi(sum,i-1)*qmi(2,n*(m-i)))%mod;
		}
	} 
	cout << res << endl;
}

signed main()
{
	init();//计算组合数 
	int T;
	cin >> T;
	while(T--) solve();
	return 0;
 } 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值