20170722考试总结

上午:

第一题:回文图

题目描述


输入

第一行,三个空格间隔的整数 n,m,k
接下来 m 行,每行两个整数 x 和 y,表示坐标为(x,y)的格子已被涂上了颜色(0 <= x,y <
n)。

输出

输出仅一行为一个整数,表示方案总数,结果可能很大,请输出 Mod 100 000 007 后
的结果。

样例输入

 (如果复制到控制台无换行,可以先粘贴到文本编辑器,再复制)

4 2 3
1 1
3 1

样例输出

3

提示

0<=n<=10000,0<=m<=2000,0<=k<=1000000

题解: 满足题意的解必须8个方向对称,开个map记录那些“组”的格子颜色已确定,最后乘法原理(=@__@=)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
const int N=10000+10;
const long long mod=100000007;
int n,m,x,y;
long long k,tot,f[N];
map<pair<int,int>,bool > flag;
void work(int i,int j){
	if(flag[make_pair(i,j)]==1) return ;
	flag[make_pair(i,j)]=flag[make_pair(i,n-j+1)]=
	flag[make_pair(n-i+1,j)]=flag[make_pair(n-i+1,n-j+1)]=
	flag[make_pair(j,i)]=flag[make_pair(n-j+1,i)]=
	flag[make_pair(j,n-i+1)]=flag[make_pair(n-j+1,n-i+1)]=1;
	tot++;
}
long long qpow(long long tmp,long long p){
	long long res=1LL;
	while(p){
		if(p&1) res=res*tmp%mod;
		p>>=1,tmp=tmp*tmp%mod;
	}
	return res;
}
int main(){
	scanf("%d %d %lld",&n,&m,&k);
	f[1]=f[2]=1LL;
	for(int i=3;i<=n;i++)
		f[i]=((i+1)>>1LL)+f[i-2];
	for(int i=1;i<=m;i++){
		scanf("%d %d",&x,&y);
		work(x+1,y+1);
	}
	printf("%lld\n",qpow(k,f[n]-tot));
}

成绩:AC

分析:其实就一个大水题,虽然最后A了,然而读题时读了很久o(╯□╰)o,对于翻转的理解开始想了很久。。尴尬O__O"…


第二题:体检

题目描述

开学了学校要求进行入学体检。

到了校医务室门口,发现有好多学生在排队,人数还在不断增加。

有多个体检项目要做。每个项目都有很多人在排队。队伍的长度在随着时间变长。该选哪一个队伍排队呢?这成了一个问题。你要安排一下体检顺序,尽可能早的完成所有项目的体检。

输入

 第一行一个整数n,表示要体检的项目数量

    接下来n行,每行表示一个体检项目。每行两个整数ab,描述该项目的情况:

       1.如果在第0时刻加入了这只队伍,需要等待a秒钟才能完成该项目的检查。

       2.不在这个队伍里,随时间队伍会变得越来越长,等待的时间每秒钟会增加b秒。

输出

一个整数表示完成体检最短需要花费的时间。

    结果可能很大,所以请mod (365×24×60×60)再打印出结果

对于50%的数据有:0<n<=1000     0<=a,b<=30000

对于100%的数据有:0<n<=100000   0<=a,b<=50000

样例输入

 (如果复制到控制台无换行,可以先粘贴到文本编辑器,再复制)

5
1 2
2 3
3 4
4 5
5 6

样例输出

1419

提示

按以下次序体检


1.在第一个队伍中花了1


2.在第二个队伍中花了5


3.在第三个队伍中花了27


4.在第四个队伍中花了169


5.在第五个队伍中花了1217


所以总时间是1419


题解: 一道比较明显的贪心题目,如果i排在j前面更优,那么ai+aj+ai*bj<aj+ai+aj*bi => ai*bj<aj*bi => ai/bi<aj/bj

所以按a/b从小到大排序。O(∩_∩)O~~

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=100000+10;
const int mod=365*24*60*60;
struct node{
	long long a,b;
	bool operator < (const node &x)const{
		return a*x.b<b*x.a;
	}
}arr[N];
int n;
long long ans;
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%lld %lld",&arr[i].a,&arr[i].b);
	sort(arr+1,arr+n+1);
	for(int i=1;i<=n;i++)
		ans=((ans+arr[i].a)%mod+arr[i].b*ans%mod)%mod;
	printf("%lld\n",ans);
}


成绩:AC

分析:整场考试做的最顺的一道题,毕竟前几天才练了类似的贪心题


第三题:龙珠雷达

题目描述

 你得到了一个龙珠雷达,它会告诉你龙珠出现的时间和地点。

 龙珠雷达的画面是一条水平的数轴,每一个窗口时间,数轴的某些点上会出现一种龙珠,每当你获得其中一颗龙珠,其它龙珠就会消失。下一个窗口时间,数轴上又会出现另一种龙珠总共有n个窗口时间,也就是总共有n种龙珠。

假设你会瞬间移动,你从数轴的x点移动到y点,耗时0秒,但是需要耗费|x-y|的体力。同时,挖出一颗龙珠也需要耗费一定的体力。请问,最少耗费多少体力,就可以收集齐所有种类的龙珠。

输入

第一行,三个整数n,m,x,表示共有n个窗口时间,每个窗口时间会出现m个龙珠,x是一开始你所处的位置。

    接下来有两个n*m的矩阵。

    对于第一个矩阵,坐标为(i,j)的数字表示第i个窗口时间,第j个龙珠的位置。

    对于第二个矩阵,坐标为(i,j)的数字表示第i个窗口时间,挖取第j个龙珠所需的体力。

输出

 一个整数,表示所需最小体力

样例输入

 (如果复制到控制台无换行,可以先粘贴到文本编辑器,再复制)

3 2 5
2 3
4 1
1 3
1 1
1 3
4 2

样例输出

8

提示

所有数据均为整数


数轴范围在030000


挖一颗龙珠所需体力不超过30000


结果保证在int范围


对于50%的数据,1<=n<=50,1<=m<=500


对于100%的数据,1<=n<=50,1<=m<=5000


题解:(⊙o⊙)…,这道题是很明显的dp,方程式也很好想dp[i][j]表示i时刻站在位置j(有龙珠)上的最小体力。

dp[i][pos[j]]=min(dp[i-1][pos[k]]+abs(pos[j]-pos[k])+w[i][j]),重点在于优化,其实优化也是很好想的,abs展开后,用两个单调队列分别dp[i-1][pos[k]]-pos[k]和dp[i-1][pos[k]]+pos[k],重点在于写的时候顺序很恶心,维护dp[i-1][pos[k]]-pos[k]时需要倒过来,防止一些pos较大但更优的值被较小的j误弹。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<deque>
using namespace std;
const int N=50+10;
const int M=5000+10;
const int L=30000+10;
const int inf=0x3f3f3f3f;
struct node{
	int num,pos;
	node(){}
	node(int a,int b){
		num=a,pos=b;
	}
}now;
deque<node> Fron;
deque<node> Bac;
struct Node{
	int pos,w;
	bool operator < (const Node &a)const{
		return pos<a.pos;
	}
}arr[N][M];
int n,m,start;
int dp[N][L];
int main(){
	scanf("%d %d %d",&n,&m,&start);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			scanf("%d",&arr[i][j].pos);
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++)
			scanf("%d",&arr[i][j].w);
		sort(arr[i]+1,arr[i]+m+1);
	}
	memset(dp,0x3f,sizeof dp);
	dp[0][start]=0,arr[0][1].pos=start;
	for(int i=1;i<=n;i++){
		Fron.clear();
		Bac.clear();
		for(int j=1;j<=m;j++){
			//if(i==1&&j>1) break ;
			now=node(dp[i-1][arr[i-1][m-j+1].pos]-arr[i-1][m-j+1].pos,arr[i-1][m-j+1].pos);
			while(!Fron.empty()&&Fron.back().num>now.num)
				Fron.pop_back();
			Fron.push_back(now);
			
			now=node(dp[i-1][arr[i-1][j].pos]+arr[i-1][j].pos,arr[i-1][j].pos);
			while(!Bac.empty()&&Bac.back().num>now.num)
				Bac.pop_back();
			Bac.push_back(now);
		}
		for(int j=1;j<=m;j++){
			while(!Fron.empty()&&Fron.front().pos>arr[i][m-j+1].pos)
				Fron.pop_front();
			if(!Fron.empty())
				dp[i][arr[i][m-j+1].pos]=min(dp[i][arr[i][m-j+1].pos],Fron.front().num+arr[i][m-j+1].pos+arr[i][m-j+1].w);
			while(!Bac.empty()&&Bac.front().pos<arr[i][j].pos)
				Bac.pop_front();
			if(!Bac.empty())
				dp[i][arr[i][j].pos]=min(dp[i][arr[i][j].pos],Bac.front().num-arr[i][j].pos+arr[i][j].w);
		}
	}
	int ans=inf;
	for(int i=1;i<=L;i++)
		ans=min(ans,dp[n][i]);
	printf("%d\n",ans);
}
/*
3 2 5

2 3
4 1
1 3

1 1
1 3
4 2
*/
成绩:AC

分析:单调队列不是很熟,写时还是调了一会,其实当时聪明一点写线段树可能反而节省更多时间。

 

总结:虽然第一题读了半天题但最后还是难得的AK了一次~\(≧▽≦)/~啦啦啦,不过说真的,如果不是别人提醒了一下,第一题还真不知道最后会怎么样。。O__O"…23333333333333

03-26
### 逆向工程与反编译概述 逆向工程是一种通过对软件的目标代码进行分析,将其转化为更高级别的表示形式的过程。这一过程通常用于研究现有系统的内部结构、功能以及实现细节。在Java和Android领域,反编译工具被广泛应用于逆向工程中。 #### Java逆向工程中的Jad反编译工具 Jad是一款经典的Java反编译工具,能够将`.class`字节码文件转换为可读的`.java`源代码[^1]。虽然它可能无法完全恢复原始源代码,但它提供了足够的信息来帮助开发者理解已编译的Java程序逻辑。Jad支持多种反编译模式,并允许用户自定义规则以适应不同的需求。此外,其命令行接口和图形界面使得复杂代码的分析变得更加便捷。 #### Android逆向工程中的JEB反编译工具 针对Android应用的逆向工程,JEB是由PNF Software开发的一款专业级工具[^2]。相较于其他同类产品,JEB不仅具备强大的APK文件反编译能力,还能对Dalvik字节码执行高效而精准的操作。它的核心优势在于以下几个方面: - **广泛的平台兼容性**:除Android外,还支持ARM、MIPS等多种架构的二进制文件反汇编。 - **混淆代码解析**:内置模块能有效应对高度混淆的代码,提供分层重构机制以便于深入分析。 - **API集成支持**:允许通过编写Python或Java脚本来扩展功能并完成特定任务。 #### APK反编译流程及其意义 当涉及到具体的APK包时,可以通过一系列步骤提取其中的信息来进行全面的安全评估或者学习目的的研究工作[^3]。这些步骤一般包括但不限于获取资产目录(`assets`)内的资源数据;解密XML配置文档如`AndroidManifest.xml`定位应用程序启动点;最后利用上述提到的各种专用软件重现整个项目框架供进一步探讨。 ```bash # 使用apktool反编译APK示例 apktool d your_app.apk -o output_directory/ ``` 以上命令展示了如何借助开源工具ApkTool轻松拆卸目标安卓档案至易于探索的状态下。 ### 结论 无论是传统的桌面端还是现代移动端环境里头,恰当运用合适的反编译解决方案都是达成逆向工程项目成功不可或缺的一环。每种工具有各自专精之处,在实际应用场景当中应当依据具体需求做出明智的选择。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值